BoilerplateHub

Next.js + Firebase + Clerk + Lemon Squeezy

Next.js with Firebase, Clerk and Lemon Squeezy is the realtime app that wants to start charging without building billing. Firestore drives the live screens, Clerk covers login and profile UI, and Lemon Squeezy sells as merchant of record. It suits an indie product with interactive features where tax compliance is not something you want to own.

Next.js FirebaseClerkLemon Squeezy

Database

Firebase

With Lemon Squeezy the only billing data Firestore needs is an entitlement document per user: the order or subscription ID, the variant and whether access is live. Keep it in a collection client code can read but never write, and enforce that in security rules, since those rules are the only thing standing between a user and their own plan flag. Everything else in the database stays product data, unpolluted by billing concepts.

Authentication

Clerk

Clerk has to carry the user through a hosted checkout that is not yours. Pass the Clerk user ID as custom data on the Lemon Squeezy checkout URL, then use it in the webhook to write the entitlement document under that ID. Because Clerk is also the source of the Firebase custom token, one identifier names the Firestore document, the security rule condition and the purchase record, which keeps the lookup path short.

Payments

Lemon Squeezy

Lemon Squeezy suits this stack because there is no server-side billing logic to host. A Next.js route handler receives the webhook, verifies the signature and writes one document. Licence keys, receipts, tax and affiliate payouts all live on their side. The limit is customization: checkout and the customer portal belong to them, so an in-app upgrade flow means redirecting out and back rather than building the whole experience yourself.

What to watch out for

Three vendors each own a slice of the same user and none of them talk to each other. Clerk knows who someone is, Lemon Squeezy knows what they bought, and Firestore is where those two facts are meant to meet. Every webhook you skip wiring leaves a gap, particularly around expiry, where nothing prompts you to revoke access unless cancellation and payment failure events are handled explicitly.

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 Firebase, Clerk and Lemon Squeezy.

## Stack

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