Web Growth: charge for it.
- Users
- Hundreds to tens of thousands
- Team
- Two to five engineers, each with agents
You are here if
- Customers notice when something breaks
- More than one person merges to main in a week
- You have a billing provider and a support inbox
- You need to know what changed and why, weeks later
Growth is where most products live longest, and where agent workflows pay off most. The codebase is still one app, but it now needs the guardrails that let several people and their agents change it in parallel: strict types end to end, a schema that generates both the migrations and the validation, feature folders so a change stays in one place, and CI that is fast enough to run on every push.
What changes when you leave this tier: teams, regions or compliance force boundaries you can no longer keep implicit. Until then, resist splitting the app. A well-organised monolith is the most agent-friendly architecture there is.
SEO-driven · content & search
Astro SSR + Postgres on Cloudflare
Thousands of dynamic, indexable pages from a database, rendered at the edge, with islands only where users act.
The stack
- Framework
- Astro (server output, Cloudflare adapter)
- Data
- Postgres (Supabase or Neon) via Drizzle
- Auth
- Supabase Auth or Lucia, only where pages need it
- Hosting
- Cloudflare Pages / Workers
- Also
-
- Tailwind CSS
- Static pre-rendering for pages that rarely change
- Programmatic sitemap and JSON-LD per route
Why agents do well here
5/5- Astro's per-route choice between static and server rendering is one line, so the agent can reason about caching without a CDN configuration.
- Directory and marketplace pages are templates over rows; the agent handles "one query, one template" patterns reliably.
- The rendering model stays HTML-first, which keeps SEO regressions visible in the page source instead of hidden in hydration.
Avoid at this tier
- Moving to a full app framework because a few pages need state; use islands.
- Client-side data fetching for anything that should be indexed.
- Bespoke caching layers before you have measured a slow route.
SaaS · logged-in product
Next.js + Prisma + Postgres
The well-trodden SaaS monolith, organised by feature, with a schema the agent and the migration tool both read.
The stack
- Framework
- Next.js App Router
- Data
- Managed Postgres (Neon, Supabase or RDS) via Prisma
- Auth
- Auth.js or Clerk
- Hosting
- Vercel, or a container on Fly / Railway
- Also
-
- Tailwind CSS + shadcn/ui
- Stripe Billing with webhook handlers as jobs
- Inngest or a Postgres-backed queue for side effects
- Playwright smoke tests in CI
Why agents do well here
5/5- Prisma's schema file is the most widely documented ORM format in existence; agents generate correct migrations and queries from it with very few misses.
- Feature folders keep a billing change inside
features/billing/, so the agent's diff stays local and reviewable. - Next.js conventions are strong enough that generated code matches the surrounding code, which is what keeps a growing codebase consistent.
Avoid at this tier
- Splitting into services because the app "feels big"; split modules, not deployables.
- Custom auth; the failure modes are exactly the ones an agent does not see.
- Handling webhooks synchronously; every side effect becomes a job.
Tool · utility & internal
SvelteKit + Drizzle + Postgres
Less code per screen than any React stack, with server loaders and form actions the agent can follow top to bottom.
The stack
- Framework
- SvelteKit
- Data
- Postgres via Drizzle
- Auth
- Lucia or Auth.js, only if the tool has users
- Hosting
- Cloudflare, Vercel, or a container
- Also
-
- Tailwind CSS
- Superforms + Zod for every form
- Vitest for loaders and actions
Why agents do well here
4/5- Load functions and form actions put data in and data out next to the page, which is the locality that keeps an agent's change in one file.
- Svelte components are shorter than the React equivalent, so more of the tool fits in context at once.
- Drizzle keeps the schema as readable TypeScript, so the agent sees the data model without opening a database client.
Avoid at this tier
- Reaching for a client store when a load function would do.
- A separate API when actions already are the API.
- React because the team knows it; a tool is small enough to learn on.