Execute choose and implement Vercel validated architecture blueprints for different scales. Use when designing new Vercel integrations, choosing between monolith/service/microservice architectures,...
Choose the right Vercel architecture based on team size, traffic patterns, and technical requirements. Covers five validated blueprints from static site to multi-project enterprise deployment, with migration paths between them.
Best for: Marketing sites, docs, blogs, landing pages Team size: 1-3 developers Traffic: Any (fully CDN-served)
project/
āāā public/ # Static assets
āāā src/
ā āāā pages/ # Static pages (SSG)
ā āāā components/ # React components
āāā vercel.json # Headers, redirects
āāā package.json
// vercel.json
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=3600, stale-while-revalidate=86400" }
]
}
]
}
Key decisions:
Best for: SaaS applications, dashboards, e-commerce Team size: 2-10 developers Traffic: Low to high
project/
āāā src/
ā āāā app/
ā ā āāā api/ # Serverless API routes
ā ā āāā (marketing)/ # Static public pages
ā ā āāā dashboard/ # Dynamic authenticated pages
ā āāā lib/ # Shared utilities
ā āāā components/ # UI components
ā āāā middleware.ts # Edge auth + routing
āāā prisma/ # Database schema
āāā vercel.json
āāā package.json
// vercel.json
{
"regions": ["iad1"],
"functions": {
"src/app/api/**/*.ts": {
"maxDuration": 30,
"memory": 1024
}
}
}
Key decisions:
app/api/ for backend logicBest for: Mobile app backends, microservices, webhook processors Team size: 1-5 developers Traffic: API-driven
project/
āāā api/ # Serverless functions (one per route)
ā āāā users/
ā ā āāā index.ts # GET/POST /api/users
ā ā āāā [id].ts # GET/PUT/DELETE /api/users/:id
ā āāā webhooks/
ā ā āāā stripe.ts # POST /api/webhooks/stripe
ā āāā health.ts # GET /api/health
āāā lib/ # Shared utilities
āāā vercel.json
āāā package.json
// vercel.json
{
"regions": ["iad1", "cdg1"],
"rewrites": [
{ "source": "/v1/(.*)", "destination": "/api/$1" }
],
"headers": [
{
"source": "/api/(.*)",
"headers": [
{ "key": "Access-Control-Allow-Origin", "value": "https://myapp.com" },
{ "key": "Access-Control-Allow-Methods", "value": "GET,POST,PUT,DELETE" }
]
}
]
}
Key decisions:
/v1/* ā /api/*)Best for: Multiple related apps, shared component libraries Team size: 5-20 developers Traffic: Varies per app
monorepo/
āāā apps/
ā āāā web/ # Main website (Vercel project 1)
ā ā āāā src/
ā ā āāā vercel.json
ā ā āāā package.json
ā āāā docs/ # Documentation site (Vercel project 2)
ā ā āāā src/
ā ā āāā vercel.json
ā ā āāā package.json
ā āāā admin/ # Admin dashboard (Vercel project 3)
ā āāā src/
ā āāā vercel.json
ā āāā package.json
āāā packages/
ā āāā ui/ # Shared component library
ā āāā config/ # Shared ESLint, TS config
ā āāā utils/ # Shared utilities
āāā turbo.json
āāā pnpm-workspace.yaml
āāā package.json
Vercel auto-detects monorepos and builds only the affected app:
// apps/web/vercel.json
{
"ignoreCommand": "npx turbo-ignore"
}
Each app in apps/ is a separate Vercel project with its own domain, env vars, and deployment settings.
Best for: Large organizations with independent teams Team size: 20+ developers across multiple teams Traffic: High
Each zone is an independent Vercel project:
Zone 1: marketing.company.com ā Marketing team's Next.js app
Zone 2: app.company.com ā Product team's Next.js app
Zone 3: docs.company.com ā Docs team's Next.js app
Zone 4: api.company.com ā Platform team's API-only project
Main project uses multi-zones (next.config.js):
// Main app: next.config.js
module.exports = {
async rewrites() {
return [
{
source: '/docs/:path*',
destination: 'https://docs.company.com/docs/:path*',
},
{
source: '/blog/:path*',
destination: 'https://marketing.company.com/blog/:path*',
},
];
},
};
Key decisions:
| Factor | Static | Full-Stack | API-Only | Monorepo | Multi-Zone |
|---|---|---|---|---|---|
| Team size | 1-3 | 2-10 | 1-5 | 5-20 | 20+ |
| Deploy independence | N/A | Single | Single | Per-app | Per-team |
| Frontend | Yes | Yes | No | Yes | Yes |
| Database | No | Yes | Yes | Per-app | Per-zone |
| Complexity | Low | Medium | Low | Medium | High |
| Cost | Low | Medium | Low | Medium | High |
Static Site ā Full-Stack Next.js ā Monorepo ā Multi-Zone
ā ā ā ā
Start here Add API routes Add shared Split teams
Add auth packages Independent
Add database deployments
| Error | Cause | Solution |
|---|---|---|
| Monorepo builds all apps | Missing ignoreCommand |
Add npx turbo-ignore |
| Multi-zone routing conflict | Overlapping paths | Ensure rewrites don't conflict |
| Shared package not found | pnpm workspace misconfigured | Check pnpm-workspace.yaml includes |
| API-only 404 on root | No public/index.html |
Add a minimal index or redirect |
For a growing product, keep /app/* in the existing Next.js deployment and place a new independently released documentation zone under /docs/*. Write explicit non-overlapping rewrites, use a shared identity provider rather than forwarding session secrets, and deploy the new zone behind a preview hostname. Exercise both routes, a signed-out flow, and the rollback rewrite before moving production traffic; retain the prior routing configuration until the cutover has been observed.
For known pitfalls and anti-patterns, see vercel-known-pitfalls.