Deploy Slim Minima in 30 minutes on Vercel and Neon

Zero to a live Slim Minima site in roughly half an hour. Create a Neon database, set five env vars, push to Vercel, and log in at /admin.

A stopwatch on a clean surface, representing deploying a site in about thirty minutes

Most "deploy in 5 minutes" tutorials lie by leaving out the part where you wire up a database, generate secrets, and figure out why the build fails on a fresh machine. I would rather give you the honest version. To deploy Slim Minima from nothing to a live site with a working admin panel takes me about 30 minutes, and most of that is creating accounts and copying connection strings, not fighting the code.

If you already have accounts on Vercel, Neon, and Cloudinary, the actual deploy is two env vars to ship and three more to handle media. The rest is paperwork.

This is the practical quickstart. I will tell you exactly what to create, what to paste where, and what you can skip on the first pass.

What you need before you start

You need three accounts and a domain. All three services have a free tier that is enough to run a real content site.

  • A Vercel account. This is the host. It runs the Next.js app and the daily cron job.
  • A Neon account. This is the Postgres database where your pages, posts, and settings live.
  • A Cloudinary account. This stores and serves your images. You can ship without it, but you will not be able to upload media until it is set.
  • A domain. This is the only thing that costs money. A cheap TLD runs roughly 2 to 3 USD per year. You can also start on the free *.vercel.app URL and add the domain later.

I wrote a full breakdown of what those free tiers actually cover in how far does the free stack stretch. The short version, as of June 2026: Vercel Hobby gives 100 GB of bandwidth and 1M requests a month, Neon free gives 0.5 GB of storage, and Cloudinary free gives 25 GB of storage and delivery. That is comfortably free for most small sites.

You also need Node installed locally and the Slim Minima repo. Clone or fork it from github.com/geraldho81/slim-minima. Forking is the better choice if you want your own copy to push to Vercel.

The short version

Here is the whole flow in one breath. Create a Neon database and copy the pooled connection string. Clone the repo. Set five environment variables. Run the migrations and seed locally to confirm it works. Push to Vercel and paste the same env vars. The Vercel build runs the migrations and then builds the site. Open /admin and log in.

Now the long version, step by step.

Step by step: from zero to live

  1. Create the Neon database. Sign in to Neon, create a new project, and let it create the default database. On the connection screen, copy the connection string. This is the single most common place people trip: you want the pooled string, the one with -pooler in the host. Slim Minima needs the pooled connection because it runs on serverless functions that open many short-lived connections. Keep this string handy as your DATABASE_URL.

  2. Clone or fork the repo and install. Fork the repo to your own GitHub account, then clone your fork. Run npm install in the project folder.

  3. Create your local env file. Copy the example: cp .env.example .env.local. Open .env.local and fill in the values from the next steps.

  4. Set DATABASE_URL. Paste the pooled Neon string you copied in step 1.

  5. Generate AUTH_SECRET. This signs your login sessions, so it has to be a real random value, not a placeholder. Generate one with openssl rand -base64 32 and paste the output. Auth.js uses this to sign the JWT session, so if it is missing or weak, your logins break.

  6. Add the Cloudinary keys. In your Cloudinary dashboard, find the cloud name, API key, and API secret. Set CLOUDINARY_CLOUD_NAME, CLOUDINARY_API_KEY, and CLOUDINARY_API_SECRET. Browser uploads use a server-signed signature, so these stay on the server and are never exposed to the page. If you want to skip media for now, you can leave these and add them before you upload your first image.

  7. Set CRON_SECRET. This protects the daily cron route that purges old trashed media. Generate another random value the same way, with openssl rand -base64 32, and paste it. Vercel passes this secret when it calls the cron, so a random string is also fine.

  8. Run the migrations. Run npm run db:migrate. This creates the tables in your Neon database using Drizzle Kit. If your DATABASE_URL is wrong, this is where it tells you.

  9. Seed the database. Run npm run seed. This creates your first admin user and a few sample pages (a home, an about, and a blog). Note the admin email and password it sets up so you can log in later.

  10. Run it locally. Run npm run dev and open the local URL. You should see the seeded site. Visit /admin, log in with the seeded credentials, and confirm the editor loads. This local check is worth the two minutes: if it works here, it will work on Vercel.

  11. Push to GitHub. Commit anything you changed and push to your fork. Vercel deploys from this repo.

  12. Import the project into Vercel. In Vercel, create a new project and import your fork. Vercel detects Next.js automatically, so you do not need to change the build settings.

  13. Paste the environment variables into Vercel. Add the same variables you set locally: DATABASE_URL, AUTH_SECRET, the three CLOUDINARY_* values, and CRON_SECRET. The minimum to ship a working site is DATABASE_URL and AUTH_SECRET. Add Cloudinary too if you want media on day one.

  14. Deploy. Start the deploy. The build command runs your Drizzle migrations first, then runs next build. This ordering matters: if a migration fails, the whole build fails, so a broken schema never reaches production. There is no separate preview database, so previews migrate the same Neon database.

  15. Log in and confirm. When the deploy finishes, open your Vercel URL and go to /admin. Log in with the admin account from the seed step. You now have a live CMS. Add your domain in Vercel when you are ready.

That is it. The daily trash-purge cron is configured automatically through the project's vercel.json, so you do not set up a separate scheduler.

The minimum to ship, and what you can defer

People over-prepare for the first deploy. You do not need email, you do not need a custom domain, and you do not strictly need Cloudinary to get the site running.

  • Mandatory to boot: DATABASE_URL and AUTH_SECRET. With just these two, the site renders and you can log in.
  • Needed for media: the three CLOUDINARY_* keys. Without them, pages and posts work, but image uploads will not. You can add these the moment you want to upload a picture, then redeploy.
  • Needed for the cron: CRON_SECRET. The daily trash purge is protected by it. Set it now so you do not forget.
  • Optional: NEXT_PUBLIC_SITE_URL (auto-detected on Vercel), CLOUDINARY_FOLDER, MEDIA_TRASH_TTL_DAYS, and the SMTP_* / EMAIL_* values for contact-form email. Add email only when you actually drop a contact form on a page.

Most of your site settings, the Cloudinary connection in the admin UI, the site name, the logo, and the menus, are editable inside the CMS without a redeploy. The values above are the ones that have to live as environment variables.

Honest limitations of this setup

I am not going to pretend the free path has no edges.

The Neon free tier scales to zero after about five minutes of no traffic. The first request after a pause waits roughly half a second while the database wakes. Slim Minima caches public pages, so most visitors never feel this, but if you are the only person hitting a brand-new site, you will occasionally notice a slightly slow first load. On a paid Neon plan it stays warm.

There is no separate preview database. Preview deploys migrate the same Neon database your production site uses. For a content site that is usually fine, but if you run a destructive migration in a preview, it touches the real data. Be deliberate with schema changes.

Cloudinary is a hard dependency for media. If you genuinely do not want a third image service, this stack is not for you, though using it keeps every image off your Vercel bandwidth, which is part of why the free tier stretches so far.

And the product is young. Slim Minima is at v0.1.3 and is largely a solo and community open-source project. The upside of the MIT license is that you keep the code and the database forever and can self-host, fork, or maintain it yourself if you ever need to. That is the trade I made on purpose, and I explained the reasoning in why I built Slim Minima.

Who this quickstart is for

This is a good fit if you are comfortable copying a connection string and running three npm commands. You do not need to be a backend engineer, but you do need to be okay in a terminal for the local check.

It suits a few people in particular:

  • Vibe coders and AI-assisted developers who want a real CMS behind a Next.js site instead of a pile of markdown files.
  • Freelancers and agencies shipping a site to a client who needs to edit it without calling you. The client-ready build walkthrough goes deeper on that handoff.
  • Small businesses and portfolios where the running cost has to stay near zero.

Who should skip it: if you want a one-click hosted product with no terminal at all, a platform like Wix or Substack will be faster to start, though you give up owning the code and the database. And if you need a non-Vercel host, Slim Minima runs on any Next.js host (Netlify, Railway, Fly.io, or a VPS with a tool like Coolify for push-to-deploy), but the cron and the build-time migration story are smoothest on Vercel, which is what these steps assume.

Frequently asked questions

How long does it actually take to deploy Slim Minima? About 30 minutes if you are creating the accounts as you go. If you already have Vercel, Neon, and Cloudinary accounts, the deploy itself is closer to 10 minutes, since most of the time is spent signing up and copying connection strings.

Do I really need Cloudinary, or can I ship without it? You can ship a working site with just DATABASE_URL and AUTH_SECRET. Pages, posts, and logins all work. You cannot upload images until the three Cloudinary keys are set, so add them before you need media, then redeploy.

Why does Slim Minima need the pooled Neon connection string? It runs on serverless functions that open many short-lived database connections. The pooled string, the one with -pooler in the host, lets Neon manage that concurrency. Using the direct (non-pooled) string can exhaust connections under load.

What happens if a database migration fails during deploy? The build fails and nothing ships. The Vercel build runs migrations before next build, so a broken schema can never reach production. You fix the migration and redeploy.

Is it free to run, and what is the only real cost? The Vercel, Neon, and Cloudinary free tiers cover a typical small content site at no charge. The only mandatory cost is a domain, roughly 2 to 3 USD per year. You can even start on the free *.vercel.app URL. See how far does the free stack stretch for the limits.

Can I deploy somewhere other than Vercel? Yes. It is a standard Next.js app, so it runs on Netlify, Railway, Fly.io, or a VPS. Vercel is recommended because the build-time migrations and the daily cron are configured for it out of the box. On other hosts you wire those up yourself.

My verdict

If you can run three commands and copy a connection string, you can have a live, self-hosted CMS this afternoon for the price of a domain. Fork the repo, set DATABASE_URL and AUTH_SECRET to get it booting, add the Cloudinary keys before you upload media, and push to Vercel. For freelancers and vibe coders, this is the fastest honest path I know to a site you actually own.

If you want zero terminal and never plan to touch the code, a hosted platform will start faster, and that is a fair trade to make. Start from the Slim Minima homepage if you want the wider picture first.

#deploy Slim Minima#Slim Minima quickstart#Vercel Neon deploy#self-hosted CMS deploy