Next.js + Supabase: A Production Stack for Small Teams

September 30, 2025

I've shipped multiple production platforms on Next.js + Supabase — a hiring platform, a Skool-style community, marketing sites. For a small team that needs auth, a real database, and storage without managing infrastructure, it's hard to beat. But it has sharp edges.

Row Level Security is your backend

The biggest mental shift: with Supabase, the client talks to the database. Your security model is RLS policies, not API middleware. Write them first, not last:

create policy "Members read their community's posts" on posts for select using ( community_id in ( select community_id from memberships where user_id = auth.uid() ) );

Test policies with different users early. A missing policy fails closed (annoying); a wrong one fails open (a breach).

Server Components changed the calculus

With the App Router, most data fetching moves into server components using the service client — RLS still applies via the user's session. The client-side Supabase SDK is now mostly for realtime subscriptions and optimistic mutations. Less JavaScript shipped, fewer loading spinners.

The patterns that kept us sane

  • Database functions for multi-step writes. Creating a job posting + notifying followers + updating counts belongs in one rpc() call, not three client round-trips that can half-succeed.
  • Generated types. supabase gen types typescript on every migration. Untyped database calls are how production bugs are born.
  • Storage policies mirror table policies. A private community's images need the same access rules as its posts — easy to forget.

Where it strains

Heavy background jobs, complex search, and multi-tenant analytics will eventually want dedicated tools (queues, search engines, warehouses). That's fine. The stack's job is to get you to the point where those problems are real — with paying users — instead of imagined.

Boring, fast, and cheap to operate. For client work and early products, that's the whole brief.