BoilerplateHub

Next.js + Supabase + Supabase Auth + Stripe

Next.js with Supabase, Supabase Auth and Stripe is the default web SaaS stack, and the reason is that three of the four layers barely need integration code. Postgres holds your data and your users in the same database, and Stripe covers every subscription shape you are likely to invent. It suits a self-serve product where you want full control over billing behaviour.

Next.js SupabaseSupabase AuthStripe

Database

Supabase

Supabase gives Next.js server components a real Postgres to query directly, which matters here because Stripe makes your own database the source of truth for entitlements. Subscription status, price IDs and current period end land in ordinary columns you can join against user rows and filter with row level security. Postgres constraints keep the webhook writes honest, and the same schema is queryable from a route handler, a cron job or the SQL editor when a customer disputes a charge.

Authentication

Supabase Auth

Supabase Auth stores users in the Postgres you are already querying, so a subscriptions table takes a foreign key to the auth user and nothing needs syncing. With Stripe, that identity is also the key you stamp onto the Stripe customer object, giving you one join from a session to a plan. The Next.js server client reads the session from cookies, so a server component can decide what to render before any JavaScript reaches the browser.

Payments

Stripe

Stripe fits this stack because you control the checkout surface and the billing logic sits in your own route handlers. Proration, trials, seat counts and metered usage are all expressible without leaving the API, and the webhook stream maps cleanly onto Supabase writes. You stay merchant of record, which means pricing pages, tax collection and invoicing follow whatever rules you decide rather than a reseller's product catalogue.

What to watch out for

You are merchant of record, so VAT and sales tax registration become yours to solve the moment you sell across borders. The other friction is drift: Stripe holds authoritative subscription state and Supabase holds a copy, and one missed webhook leaves a paying customer locked out. Build a reconciliation job that re-reads Stripe subscriptions on a schedule instead of trusting the event stream alone.

Boilerplates close to this stack

Matched on Next.js plus the parts of this stack our catalog tags. Each card shows which pieces actually line up, so you can see how much you would still wire yourself.

A CLAUDE.md for this stack

The rules that matter for this combination specifically, including who owns entitlement state. Adapt the commands to your repository before committing it.

CLAUDE.md
# CLAUDE.md

This project is a Next.js SaaS on Supabase, Supabase Auth and Stripe.

## Stack

- Framework: Next.js
- Database: Supabase
- Auth: Supabase Auth
- Payments: Stripe

## Boundaries

- Never edit a migration that has already run. Write a new one.
- Never hardcode Stripe price or product identifiers in components. They belong in config.
- Never trust a client-supplied user id. Read the session from Supabase Auth on the server.
- Treat webhook handlers as idempotent. The same event will arrive twice.

## Entitlements

- Stripe is the source of truth for what a customer paid for.
- The database mirrors that state; it never decides it.
- Any check for "can this user do X" reads the mirrored entitlement, not a live API call.

## Before you say a change is done

- The app builds.
- Tests pass.
- No secret, key or webhook signing secret appears in a committed file.

Related stacks