BoilerplateHub

Next.js + Supabase + Better Auth + Lemon Squeezy

Next.js with Supabase, Better Auth and Lemon Squeezy is the fast commercial path for a solo build. Better Auth owns identity in Postgres, Lemon Squeezy owns checkout and tax, and the code between them amounts to one signed webhook handler. It suits a product with a small number of fixed plans and no appetite for billing infrastructure.

Next.js SupabaseBetter AuthLemon Squeezy

Database

Supabase

Lemon Squeezy's variants are the unit of sale, and they multiply faster than the tiers shown on a pricing page. Map variant IDs to a plan row in Postgres so application code reads a plan name and the mapping absorbs new variants without a code change. Supabase's SQL editor is genuinely useful for correcting that mapping when a customer buys the wrong thing, and its storage sits in the same project for whatever the purchase unlocks.

Authentication

Better Auth

Better Auth keeps identity in tables you control, which matters because the hosted checkout is the one part of this funnel that leaves your domain. Put the Better Auth user ID in the checkout's custom data, read it back on the order webhook, and write the entitlement against it. Turning on email verification in the library before checkout cuts down the orders that arrive attached to an address nobody can actually sign in with.

Payments

Lemon Squeezy

Lemon Squeezy is chosen here to avoid owning tax and a checkout page in the same quarter. Hosted checkout, receipts, licence keys and affiliate tracking arrive as one bundle, and the Next.js side shrinks to signature verification and a link into their customer portal. The constraint is shape rather than volume: seat-based and metered billing do not map onto a variant catalogue, so price in a way a catalogue can express.

What to watch out for

Overlay checkouts feel embedded but they still complete on Lemon Squeezy's side, so a browser landing back on your success page proves nothing about whether the order event has been delivered. Render a pending state rather than querying the entitlement table straight away. Because Better Auth also owns account deletion, decide in advance what happens to an active licence when someone deletes an account that is still being billed.

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, Better Auth and Lemon Squeezy.

## Stack

- Framework: Next.js
- Database: Supabase
- Auth: Better Auth
- Payments: Lemon Squeezy

## Boundaries

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

## Entitlements

- Lemon Squeezy 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