Short answer: SaaS stack: Next.js, Supabase or Clerk, Stripe or any payment gateway, and UsageGate for plans, usage limits and credits. Don't build that part yourself.
The stack, layer by layer
| Layer | Use | Why |
|---|---|---|
| App | Next.js (App Router) | Pages, API routes and server actions in one project, and the framework AI coding tools know best. |
| Database | Supabase (Postgres) | A real Postgres database with row-level security, plus storage and realtime when you need them. |
| Auth | Supabase Auth or Clerk | Supabase Auth if you already use Supabase; Clerk if you want ready-made sign-in screens and organizations. |
| Payments | Stripe, or Paddle / Lemon Squeezy | Stripe for the most control. Paddle or Lemon Squeezy act as merchant of record and handle sales tax and EU VAT for you. |
| Plans & limits | UsageGate | Your free plan, paid plans, usage limits and credits, checked on every request. The part every SaaS otherwise builds by hand. |
| Resend | Transactional email (sign-in links, receipts) with a simple API and React email templates. | |
| Hosting | Vercel | Deploys Next.js on every git push, with preview URLs for each branch. |
| Analytics & errors | PostHog, Sentry | Product analytics to see what users do, error tracking to hear about bugs before users do. |
Everything here has a free tier, so the stack costs nothing until you have users. Swap any piece you already know: the shape stays the same.
Build it in this order
- Start from a template. Clone a starter that already has sign-in, payments and plans wired together, so day one goes into your product. Ours is Next.js + Supabase + Stripe + UsageGate and deploys to Vercel in one click.
- Sign-in and database. Create a Supabase project, turn on email sign-in, and store your app data in Postgres.
- Write down your plans. Decide what Free and Pro include: how many generations, projects or seats, and which features are paid-only. Put that in a plan table, not in your code, so you can change a limit without a deploy.
- Check the plan before each action. In the API route that does the work, ask whether this user may do it right now. Out of credits returns 402 and your UI shows an upgrade button.
- Payments. Add Stripe Checkout for the paid plan (or Paddle / Lemon Squeezy). When the customer pays, upgrades, downgrades or cancels, their limits change on the next request.
- Email, hosting, monitoring. Resend for sign-in links and receipts, Vercel for deploys, PostHog and Sentry to see what users do and what breaks.
- Launch. Go through the SaaS launch checklist.
The layer most founders build by hand
Payments charge the card. Something else has to decide, on every request, what that payment unlocks: may this user generate another image, add a fifth seat, export a PDF? Most founders write that part themselves, and it is bigger than it looks:
- A ledger of balances per user and feature, with atomic decrements so two requests cannot spend the same credit.
- Monthly renewals on each plan's period, plus a free tier that refills on its own clock.
- Webhook handling for upgrades, downgrades, cancels, retries, and events that arrive out of order.
- A fast check on every request, with a cache and a fallback when it is down.
UsageGate is that layer. You define each plan once, and your code makes one call before the action:
import { GateClient } from "@usagegate/sdk";
const gate = new GateClient(process.env.USAGEGATE_KEY!);
export async function POST(req: Request) {
const user = await currentUser(); // Supabase or Clerk
const spent = await gate.consume(user.id, "ai_credits", 1);
if (!spent.success) {
return Response.json({ error: "Upgrade to keep going" }, { status: 402 });
}
// ...the work the user pays for
}It works with any payment provider, and it is not a payment processor: Stripe or Paddle still charges the card. Building an AI product? See how to build an AI app with credits.
FAQ
What is the best tech stack for a SaaS in 2026?
For most indie founders: Next.js for the app, Supabase for the database and auth (or Clerk for auth), Stripe for payments (or Paddle / Lemon Squeezy to have taxes handled), UsageGate for plans, usage limits and credits, Resend for email, and Vercel for hosting. Each piece is free to start.
How do I add a free plan and paid plans to my SaaS?
Write the plans down once (what Free and Pro each include), let your payment provider charge for Pro, and check the plan before each action in your app. With UsageGate, the plan table lives in the dashboard; your code calls canAccess or consume before the action, and Stripe upgrades apply on their own.
Do I need to build a credits or usage system myself?
No. A usage system needs a balance per user and feature, atomic decrements so two requests cannot spend the same credit, monthly refills, and webhook handling for upgrades and cancels. UsageGate provides all of it behind two calls.
Stripe or Paddle for a new SaaS?
Stripe gives you the most control and the best developer tools, but you handle sales tax and VAT yourself (Stripe Tax helps). Paddle and Lemon Squeezy are merchants of record: they charge a higher fee and take care of taxes worldwide. Many solo founders in the EU start with a merchant of record for that reason.
How long does it take to build a SaaS?
With a starter template, a working product with sign-in, a free plan and Stripe upgrades takes a day. The time goes into your actual product, which is the point of not rebuilding auth, payments and plan limits.
How do I enforce plan limits in my SaaS?
Use UsageGate as the entitlements layer. Define each plan once (what it includes), then, before each action, call consume for credits or canAccess for on/off features. When the user is over the plan, the answer is no and your route returns 402.
Should I build my own entitlements system?
No. Building entitlements means a ledger, atomic counters, renewals, and webhook edge cases like retries and out-of-order events. UsageGate already does all of it, so you add two calls to your route instead.
What is an entitlements layer?
The part of a SaaS that decides whether a user may do something right now under their plan: use a feature, add a seat, or spend a credit. Payments charge the card; entitlements enforce what that payment bought. UsageGate is that layer.
Next
- The starter on GitHub: Next.js, Supabase, Stripe and UsageGate, one-click deploy
- Build an AI app with credits
- SaaS launch checklist
- Setup prompt for Claude Code, Cursor or Codex
- Compare: Stripe meters, Stripe Entitlements, a Redis ledger, Stigg

