BoilerplateHub

Next.js + Turso + Better Auth + Polar

Next.js with Turso, Better Auth and Polar combines per-tenant SQLite with a merchant of record, so neither the database nor the codebase carries billing weight. Better Auth's organizations line up with tenant databases and Polar's benefits line up with entitlement checks. It suits a small-team business product sold internationally.

Next.js TursoBetter AuthPolar

Database

Turso

The per-tenant model and a merchant of record are complementary, because neither wants you keeping much billing data. A single control database maps a Polar customer to a tenant and the benefits granted to it, while every tenant database stays pure product data with no billing columns at all. That separation is also what makes edge replicas safe: the replicated data contains nothing about money and nothing requiring strong consistency.

Authentication

Better Auth

Better Auth's session and account tables belong in the control database, and its organization plugin maps naturally onto the tenant concept Turso already forces you to name. Treat the organization ID as both the key that selects a SQLite database and the reference you give Polar. Signing in resolves an organization, and the organization resolves a database and a benefit set, which is a shorter chain in practice than it reads on paper.

Payments

Polar

Polar suits a product sold to small teams because the benefit model matches entitlement checks more closely than a raw price list does. Your code asks whether this organization holds a benefit; Polar decides how that was paid for and files the tax paperwork behind it. Since the catalogue is configured outside your repository, keep the benefit-to-capability mapping in the control database where it can be versioned with your migrations.

What to watch out for

SQLite's type system is thinner than Postgres, so subscription timestamps arriving from Polar land as text or integers you have to handle consistently, and a comparison against the wrong representation returns nothing rather than raising anything. There is no timestamptz to rescue you. Pick a single storage convention for instants, enforce it in the schema, and convert once at the boundary where webhook payloads enter the system.

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 Turso, Better Auth and Polar.

## Stack

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