Deployment
Pick a deploy target and architecture, avoid blocked combinations, and ship to production.
At generatesaas init every project picks a deploy target (node or vercel, flag --deploy) and an architecture (fullstack or separate, flag --architecture), both written to .generatesaas/manifest.json as deploymentTarget and architecture. The shared Hono backend (@repo/api) deploys identically across targets; only the runtime host differs.
The two-axis matrix
The target picks the runtime host; the architecture picks where @repo/api runs. Defined in packages/cli/src/infrastructure.ts.
| Combo | fullstack | separate |
|---|---|---|
node (default, long-running container) | Allowed | Allowed |
vercel (serverless functions) | Allowed | Blocked |
fullstack- the frontend hosts@repo/apiin-process. Simplest; runs on both targets.separate- a standalone Hono server inapps/backend. Long-running only; choose for independent scaling, multiple frontends on one API, or operational isolation.
Blocked combinations
The CLI guards these before scaffolding. In the interactive flow the incompatible choice is filtered out (the only remaining option auto-selects); passing it explicitly via flags throws.
| Combo | Source | Effect | Reason |
|---|---|---|---|
separate + vercel | INCOMPATIBLE_ARCH_TARGETS | fullstack auto-selects on vercel; --architecture separate --deploy vercel throws | Standalone backends need a long-running runtime; Vercel's per-function TS check conflicts with pnpm's isolated install. |
vercel + redis | INCOMPATIBLE_COMBOS | upstash auto-selects as the only cache on vercel; --deploy vercel --cache redis throws | Serverless can't hold a persistent ioredis connection. |
Net effect of picking vercel: architecture is forced to fullstack and the cache provider is forced to upstash - the separate and redis options are hidden.
Cloudflare Workers is never a target. The boilerplate depends on Node-only modules (geoip-lite, ioredis, pg). Only node and vercel exist - do not attempt a Workers deploy.
Choose your path
Vercel
Serverless, fullstack-only. Schema-prep build step and edge-incompatible features to disable.
Self-hosting with Docker
The node target - a multi-stage Dockerfile per app on a long-running host, migrate-on-boot, your own DB + cache.
Reverse proxy
Front long-running apps by host and path: frontend, backend, and docs ports.
Separate backend
Standalone Hono server on API_PORT - TRUSTED_ORIGINS, API_URL, graceful shutdown.
Going to production
Pre-launch checklist: secrets, SEO, webhooks, migrations.
Frequently asked questions
Which combo should I default to?
The CLI default is node + fullstack - a single long-running container with @repo/api hosted in-process. It is the simplest to operate and the most portable across hosts.
Can I deploy a standalone backend to Vercel?
No. separate + vercel is refused. Either use fullstack for serverless, or deploy the standalone backend to a long-running runtime (Render, Fly.io, Railway, Coolify, Dokploy, or a VPS).
What breaks if I pick vercel?
Three features assume a long-running runtime (EDGE_INCOMPATIBLE_FEATURES) and become unavailable on edge: local file storage (use s3 storage instead), SMTP email (use resend or ses), and Content API git integration (no edge equivalent). Separately, redis cache is unavailable - the CLI forces upstash. See Vercel for the full setup.
Where do I change the target after init?
The target and architecture are baked into the scaffolded project at init time - there is no in-place switch. Re-run generatesaas init (optionally --deploy / --architecture) into a fresh project; see CLI init.