Skip to content
Get the kit

Choose your paywall

Every paid product answers three questions: what does the free plan get, is there a trial, and when do you ask for the upgrade. The kit asks them in one file, apps/extension/paywall.config.ts, and everything else follows: the same wall in every surface, a badge on locked controls, a meter on limits, a countdown on trials. You never build wall UI.

Start from one of the six recipes the setup wizard offers, or answer the questions yourself. The popup behaves the way your users’ popup will. Click its buttons and move the day forward to see each wall.

Start from a recipe

Free allowance on the core action, Pro extras locked.

1. What does the free plan get?
2. Is there a trial?

3. When do you ask for the upgrade?

paywall.config.ts

When your answers match a named recipe, one command writes the config into your clone, from anywhere inside it:

Terminal window
pnpm create extstart --recipe free-trial

In Claude Code, /change-paywall-recipe free-trial does the same with the store-policy checklist in front of the agent. A custom mix is the same command with a sentence instead of a name, or paste the config straight into paywall.config.ts. The numbers (free uses, trial days, when to ask) live in that file and change without a rerun.

Not sure which to pick? Describe your extension to your agent (what it does, what costs you money to run, who pays for tools like it) and ask which paywall setup fits. The agent reads this guide and the reference, and /change-paywall-recipe applies the answer.

  • One call at every feature. sendMessage("access", { feature }) checks the plan, counts a free use, consumes credits, and raises the wall when access is denied. Your code returns on allowed === false. See Build your feature.
  • Store policy, built in. A config with no free feature fails to build unless it says paidOnly: true, and then the listing sentence is written for you. The prompt is always dismissible. A trial ends into the free plan.
  • Sign-in only when needed. The popup opens as a guest by default; the sign-in wall appears in front of checkout and on features you mark signin: true. One line in site.config.ts makes the sign-in form the first screen instead. See when sign-in is asked.
  • The server behind it. Entitlements come from the billing webhook, trial-once and credit balances are enforced in the backend, and every access is mirrored to usage/{uid}. Client counters only time the UX.

Every value, the verdict shape, the UI pieces and the edge cases are in the paywall reference.