From Zero to First Deploy: A Next.js + Supabase Starter Stack
The minimum-viable production stack I reach for in 2026 — Next.js 16, Supabase, Tailwind, Vercel — and exactly what I skip until later.
I've built four side-projects on the same stack in the last twelve months. Here's the minimum-viable shape, what each piece does, and — more importantly — what I deliberately don't add until I have real users.
The whole stack on one page
┌──────────────────┐
│ Next.js 16 │ ← App Router, RSC, Server Actions
└────────┬─────────┘
│
┌────────────┴────────────┐
│ │
┌─────▼─────┐ ┌─────▼─────┐
│ Supabase │ │ Tailwind │
│ Postgres │ │ CSS v4 │
│ Auth/RLS │ └───────────┘
│ Storage │
└─────┬─────┘
│
┌─────▼─────┐
│ Vercel │ ← edge, ISR, image optimisation
└───────────┘
That's it. Five pieces. Total monthly cost for a low-traffic project: $0.
Why this stack, today
Next.js 16 because Server Components let you write a database-driven page without ever hand-writing an API route. You get streaming HTML, automatic ISR, and per-route caching for free.
Supabase because Postgres + Row-Level Security solves auth, storage, and the "do I really need a backend?" question in one tool. The dashboard is good enough that you can prototype without writing a migration.
Tailwind v4 because in 2026 the CSS-in-JS wars are over. Tailwind won the speed-of-iteration race; everything else is preference.
Vercel because deploying a Next.js app to Vercel takes 90 seconds and you get edge functions, image optimisation, and preview URLs without configuration. Yes, you can self-host. No, it's not worth your time on day one.
The 60-minute setup
# 1. scaffold
npx create-next-app@latest my-app --typescript --tailwind --app
# 2. add supabase
npm i @supabase/supabase-js @supabase/ssr
# 3. add the env vars
echo "NEXT_PUBLIC_SUPABASE_URL=..." >> .env.local
echo "NEXT_PUBLIC_SUPABASE_ANON_KEY=..." >> .env.local
echo "SUPABASE_SERVICE_ROLE_KEY=..." >> .env.local
# 4. ship
vercel --prod
You're live. Now do the boring parts.
Row-Level Security: do this on day one
The single biggest mistake I see in Supabase apps is skipping RLS "for now." There is no "later." Turn it on, write your first policy, then build features.
alter table public.posts enable row level security;
create policy "anyone can read published posts"
on public.posts for select
using (status = 'published');
create policy "authors can write their own"
on public.posts for all
using (auth.uid() = author_id);
Two policies. Your data is now safer than 80% of side-projects on the internet.
What I skip until I have users
| Skip | Until |
|---|---|
| Custom design system | You have a second product |
| State management library | useState gets painful |
| Unit tests for UI | You've shipped 5 features |
| CI pipeline beyond Vercel previews | You add a second contributor |
| Observability stack | Real traffic exists |
| A custom domain on day 1 | You're confident the project ships |
Every one of these is good engineering. None of them are good engineering on day one. Premature infrastructure is the most common reason side-projects die before they reach a user.
The "second deploy" checklist
Once the thing is live and someone other than you has used it:
- Add an analytics ping (Vercel Analytics or Plausible — both free tier).
- Set up Sentry for error tracking.
- Add a contact email that isn't your personal Gmail.
- Write a README that explains what the project is, not just how to run it.
- Buy the domain.