What this stack is for
This is the quick-startup stack after it finds paying customers: same bones, plus Stripe, because now there is money involved. The new complexity is not the card form; Stripe solved that years ago. It is that subscription state now lives in two systems at once, and webhooks are the only thing keeping them honest. Get the webhook handling right and everything else here is assembly.
Components
- Vercel: hosting, deploys from git, preview URLs per branch
- Vite + React: the frontend build and UI layer
- Supabase: Postgres database, auth, and row-level security
- Stripe: recurring billing, customer portal, webhook-driven subscription state
- Resend: transactional email (receipts, dunning notices)
- PostHog: product analytics and conversion funnels
How the pieces fit
- The React app builds with Vite and deploys to Vercel on every git push
- Supabase holds user accounts and subscription state behind row-level security
- Stripe Checkout handles card entry; Stripe's customer portal handles plan changes and cancellation
- A webhook endpoint receives Stripe events and updates subscription status in Supabase
- The app reads subscription status from Supabase to gate paid features
- PostHog tracks signup, trial, and upgrade events
Setup outline
- Start from the quick-startup stack: Vite + React + Vercel + Supabase (full walkthrough coming)
- Create the Stripe account and define products/prices (full walkthrough coming)
- Add Stripe Checkout and the customer portal link to the app (full walkthrough coming)
- Add the Stripe webhook route and write subscription state to Supabase (full walkthrough coming)
- Gate features in the UI based on subscription status (full walkthrough coming)
- Add PostHog events for signup, trial start, and upgrade (full walkthrough coming)
What to hand your agent
Billing is the one part of the app where "roughly correct" means a refund, so brief the agent completely:
- The full stack description above, plus the PRD and feature spec for the billing flow
- The Stripe product/price IDs and webhook signing secret, as env vars, never inline
- The instruction to treat Stripe webhook handling as idempotent, because duplicate events will arrive
Adaptation notes
- Paddle or LemonSqueezy can replace Stripe where merchant-of-record tax handling matters more than customization
- A single fixed-price plan can skip the customer portal entirely and use a Stripe Payment Link
- Usage-based billing needs a metering step before the webhook, not covered by this outline