GenerateSaaS

Vercel

Deploy the fullstack target to Vercel serverless functions, provision the managed services it needs, and swap the edge-incompatible features.

The vercel target runs the app and the shared @repo/api backend as serverless functions. It auto-selects fullstack and hides separate, because serverless cannot host a long-running process. Several flag-gated features assume a persistent runtime - swap them before you deploy.

Vercel has no startup hook, so init prepends the schema step to vercel.json's buildCommand (preserving any existing command, defaulting to pnpm build). Migrations run as part of every build, not at boot.

Deploy

Provision managed services. Serverless functions are stateless, so every dependency must be hosted:

DependencyUse
PostgresNeon or Supabase - any connection-pooled DATABASE_URL
Cache and rate limitingUpstash Redis - HTTP-based, so it survives between invocations
Background jobsA hosted Inngest app - the INNGEST_* keys. See Background jobs

Set environment variables in the Vercel project: BASE_URL, BETTER_AUTH_SECRET (min 32 chars), DATABASE_URL, the Upstash pair, and the INNGEST_* trio. Leave TRUSTED_PROXY unset - the backend recognises Vercel from its own VERCEL variable and reads the header Vercel guarantees. See Environment variables and Client IP.

Connect the repository in the Vercel dashboard, or run vercel deploy. The build runs the prepended schema step, then the app build - no separate migrate command.

Verify the deployed URL serves the app and its /api/* routes. @repo/api mounts in-process through the app's catch-all API route; there is no separate backend service to deploy.

Edge-incompatible features

These default to runtime-safe values. If you enabled a long-running variant locally, switch it before deploying.

FeatureIncompatible settingFix on Vercel
Storageconfig.storage.provider: "local"Keep "s3" (the default) - see Storage
Emailconfig.email.provider: "smtp"Set "resend" or "ses" - see Email
DatabaseSelf-hosted Postgres (databaseProvider: "postgres")Use Neon or Supabase - serverless cannot pool to a self-hosted instance, and init/update refuse the pair. See Database
CacheSelf-hosted Redis (ioredis)Use the Upstash provider - see Caching
Content APIgitCommit on with config.contentApi.enabledDisable gitCommit - the filesystem is read-only

Turning a feature off removes the incompatibility entirely: its routes and UI are hidden. The shipped defaults (storage.provider: "s3", contentApi.enabled: false) are already Vercel-safe.

Never deploy a --demo build - its schema step resets the database and force-pushes the schema on every build.

On this page