BoilerplateHub

Next.js + Supabase + Supabase Auth + Lemon Squeezy

Next.js with Supabase, Supabase Auth and Lemon Squeezy trades billing control for a much shorter path to revenue. Lemon Squeezy sells as merchant of record, so tax is handled and checkout is hosted, leaving Supabase to store little more than the entitlement each order granted. It suits a solo developer shipping a paid product without wanting to own a billing subsystem.

Next.js SupabaseSupabase AuthLemon Squeezy

Database

Supabase

Because Lemon Squeezy owns the checkout and the tax record, the Supabase schema you need is smaller than a Stripe build. You are storing an order or subscription ID, a variant ID and a status, then deriving access from that. Model entitlements as their own table keyed by user rather than scattering plan flags across profile columns, since Lemon Squeezy variants change more often than your product tiers do, and a lookup table absorbs that without a migration.

Authentication

Supabase Auth

Supabase Auth is what turns a hosted checkout into an account. The working pattern is to pass the Supabase user ID into the checkout as custom data, then read it back off the webhook to attach the purchase to the right row. Row level security then gates premium tables on the entitlement record. Without that identifier round trip you are matching on email, which breaks as soon as someone pays with a different address than they signed up with.

Payments

Lemon Squeezy

Lemon Squeezy handles the parts of selling software that have nothing to do with code: global tax remittance, invoices, receipts and a working affiliate program. Hosted checkout means no payment form inside your Next.js app and no card data near your infrastructure. The tradeoff is that the checkout looks like their checkout, and complex billing shapes such as seats or usage are awkward compared to writing them yourself.

What to watch out for

Custom data on the checkout is your only reliable link between a payment and a Supabase user, and it is easy to forget on one of several buy buttons. As merchant of record Lemon Squeezy also owns the billing relationship, so refunds, plan changes and card updates happen in their portal rather than a settings page you built. Deep link to that portal early instead of promising in-app billing management.

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

## Stack

- Framework: Next.js
- Database: Supabase
- Auth: Supabase 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 Supabase 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