BoilerplateHub

Next.js + Supabase + Better Auth + Polar

Next.js with Supabase, Better Auth and Polar puts identity in your database and tax obligations on somebody else's balance sheet. Polar sells as merchant of record while Better Auth keeps users and sessions in the Supabase Postgres you already run. It suits a developer-facing product selling licences or hosted access to a global audience.

Next.js SupabaseBetter AuthPolar

Database

Supabase

Because Polar sells as merchant of record, Postgres stops being the ledger and becomes a cache of what Polar granted. Store the Polar customer ID against the Better Auth user row plus a narrow benefits table refreshed from webhooks. Supabase handles that comfortably, and confining the mirror to one table means a full resync is a truncate and replay rather than a migration across plan flags scattered through profile columns.

Authentication

Better Auth

Better Auth's user ID is what you hand Polar as the external customer reference at checkout, which removes email matching from the equation. Sessions live in the same database as the benefits mirror, so a server component resolves person and plan in a single query. The organization plugin is worth adding early if team plans are coming, because retrofitting a company above a population of personal customers is a data migration nobody enjoys.

Payments

Polar

Polar registers and remits tax, issues the invoice under its own name, and exposes billing as an API rather than a portal-first product, which suits a codebase where checkout sessions are already created server-side. Licence keys and benefit grants are first-class concepts, so gated downloads and issued API keys have somewhere natural to live. What you concede is the legal identity on the receipt: the customer's statement says Polar.

What to watch out for

Two systems both call their records subscriptions and only one of them is right. Polar holds the truth, Supabase holds the copy, and your queries answer from the copy, so an unprocessed event looks to a customer like a feature that vanished rather than an error anyone gets paged about. Cancellations and refunds also happen inside Polar's portal, so plan for entitlement state that changes without any request ever reaching your app.

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 Polar.

## Stack

- Framework: Next.js
- Database: Supabase
- Auth: Better Auth
- Payments: Polar

## Boundaries

- Never edit a migration that has already run. Write a new one.
- Never hardcode Polar 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

- Polar 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