<!--
ROBOTS ON PAYROLL / THE VAULT
What this is: a drop-in STACK.md documenting a full SaaS stack (Next.js, Supabase, Stripe, Resend, PostHog, Sentry) with costs and swap points.
How to use it: download this file and give it to your AI (Claude, ChatGPT,
Cursor, Lovable chat) as a reference. Say: "Use this as my playbook for
documenting and questioning my stack."
Latest version + full guide: https://robotsonpayroll.com/resources/saas-starter-stack
-->

# STACK.md

> Drop this file in the root of your repo. It documents every tool in the stack, what it costs, why it was chosen, and when to replace it. Your AI agents will read it too, so keep it current: an agent that knows "we use Supabase RLS, never a service-role key in client code" writes safer code on the first pass.
>
> Prices verified July 2026. Re-check before trusting any number older than 6 months.

## The stack at a glance

| Layer | Tool | Cost at 0 users | Cost at ~100 users | Cost at ~10K users |
|---|---|---|---|---|
| Framework | Next.js App Router (v16) + TypeScript + Tailwind + shadcn/ui | $0 | $0 | $0 |
| Hosting | Vercel | $0 (Hobby, pre-launch only) | $20 (Pro, required for commercial use) | $20-60 |
| Database + Auth + Storage | Supabase | $0 | $0 (free tier covers it) | $25 Pro |
| Payments | Stripe | $0 | ~2.9% + $0.30 per charge | Same rates, +0.7% if using Stripe Billing |
| Transactional email | Resend | $0 (3K emails/mo free) | $0 | $20 Pro (50K emails/mo) |
| Product analytics | PostHog | $0 (1M events/mo free) | $0 | $0-50 |
| Error tracking | Sentry | $0 (5K errors/mo free) | $0 | $26 Team (annual) |
| **Total fixed** | | **$0** | **$20-29/mo** | **~$120-250/mo** |

Later additions (only when triggered, see "Upgrade triggers" below):

| Layer | Tool | When | Cost |
|---|---|---|---|
| Cache / rate limits / queues | Upstash Redis | First abuse incident or first background job | $0-10 |
| Heavy file storage | Cloudflare R2 | Files past Supabase's included storage, or egress-heavy files | ~$1-10, $0 egress always |
| Marketing / lifecycle email | Loops | When you have a list worth emailing (500+ signups) | $0 to 1K contacts, then $49+ |
| Web analytics | Plausible | If you want cookieless marketing-site numbers | $9-19 |

## Why each tool (and the alternative I rejected)

### Next.js App Router
Not because it is the most loved framework in 2026 (it is not, RSC complexity is real). Because **AI coding agents are measurably stronger at React/Next.js than anything else**. The training-data moat compounds: your agent one-shots things in Next it fumbles in SvelteKit. When the agent writes 90% of the code, agent fluency beats your personal preference.
Rejected: SvelteKit (93% dev satisfaction, smaller bundles, weaker AI assistance, that tradeoff is the whole ballgame). Remix (merged into React Router v7, no longer a mainstream new-project pick).

### Vercel
Zero-config deploys for Next.js, preview URLs per branch, and your agent already knows its conventions. Hobby is strictly non-commercial with hard usage stops, so the day you charge money you owe $20/mo for Pro. Budget it.
Rejected for v1: self-hosting on a VPS. Cheaper at scale, but you are one person and your time is the scarce resource.

### Supabase (Postgres + Auth + Storage in one)
One vendor for DB, auth, and file storage means one dashboard, one client library, and auth identities that live in the same Postgres as your data, which is what makes **Row Level Security** practical. RLS is the single highest-value security decision in this stack: even if your agent writes a buggy query, the database refuses to return rows the user does not own.
Free tier: 500 MB DB, 50K auth MAU, 1 GB storage. Note free projects pause after 1 week of inactivity. Go Pro ($25) at launch for no-pause plus backups.
Rejected: Neon + Drizzle + Better Auth (excellent, arguably cheaper at 10K users since Better Auth is $0 and Neon's post-Databricks pricing is very cheap, but it is three tools to wire instead of one). Clerk (fastest prebuilt auth UI, Hobby is now 50K MRU free as of Feb 2026, but the B2B orgs add-on is $100/mo and your data lives in their system).

### Stripe
2.9% + $0.30 per US card charge, unchanged in 2026. Stripe Billing (subscriptions) is now a flat 0.7% of billing volume. Not the cheapest, but the docs, the test mode, and the agent fluency are unmatched.
Rejected: Lemon Squeezy / Paddle (merchant-of-record is genuinely useful for global sales tax, revisit when tax filings hurt).

### Resend
Transactional email that works in 10 minutes, react-email templates your agent can write, 3,000 emails/mo free (100/day cap). $20 Pro at 50K emails/mo.
Rejected: SES (cheapest per email, worst DX, save it for when email is a real line item).

### PostHog
Product analytics, session replays, and feature flags in one, with 1M events/mo free per product. 98% of PostHog customers pay $0. Replays are usually the first thing that costs money; set billing limits in the dashboard on day one.
Rejected: paying for analytics before you have users to analyze.

### Sentry
5K errors/mo free forever on the Developer plan. You will find out about bugs from Sentry before users email you, which at one-person scale is the difference between a fix and a churn.

## Non-negotiable rules for this repo (agents: read this)

1. **RLS on every table, no exceptions.** Every table gets `ENABLE ROW LEVEL SECURITY` plus explicit policies in the same migration that creates it.
2. **The Supabase service-role key never ships to the client.** Server-only. Any file importing it must be server-only code.
3. **Subscription state changes in exactly one place: the Stripe webhook handler.** Never trust the client's word that someone paid. Verify webhook signatures, handle events idempotently.
4. **All env vars validated at boot** (zod schema). The app should crash loudly at startup with a missing var, not 500 mysteriously at runtime.
5. **Secrets live in `.env.local` and the Vercel dashboard.** `.env.local` is gitignored. `.env.example` is committed with placeholder values only.

## Upgrade triggers (when to change something)

- **Supabase free to Pro ($25):** the day you launch. Free projects pause after 1 week idle; a paused DB during a launch spike is a self-inflicted outage.
- **Add Upstash Redis:** first time you need rate limiting (someone hammers your API) or your first background job longer than a request cycle.
- **Add R2:** when user files outgrow Supabase storage or your egress bill appears. R2 egress is $0, always.
- **Add Loops:** at 500+ signups. Transactional (Resend) and marketing (Loops) email are different jobs; do not send newsletters through your transactional domain.
- **Vercel Hobby to Pro ($20):** before your first paying customer, not after. Hobby is non-commercial and hard-stops on overage with a 30-day wait.
- **Consider migrating off Vercel entirely:** if hosting passes ~$200/mo sustained. Not before. (See the deep-dive in the vault item.)

## Cost reality check

- Pre-launch: $0.
- ~100 users: $20-29/mo. The only forced spend is Vercel Pro.
- ~10K users: roughly $120-250/mo total, plus Stripe's cut of revenue. If someone quotes you a $2K/mo infra bill for a 10K-user SaaS in 2026, they are solving a problem you do not have.

*Prices as of July 2026: vercel.com/pricing, supabase.com/pricing, stripe.com/pricing, resend.com/pricing, posthog.com/pricing, sentry.io/pricing.*
