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:
| Dependency | Use |
|---|---|
| Postgres | Neon or Supabase - any connection-pooled DATABASE_URL |
| Cache and rate limiting | Upstash Redis - HTTP-based, so it survives between invocations |
| Background jobs | A 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.
| Feature | Incompatible setting | Fix on Vercel |
|---|---|---|
| Storage | config.storage.provider: "local" | Keep "s3" (the default) - see Storage |
config.email.provider: "smtp" | Set "resend" or "ses" - see Email | |
| Database | Self-hosted Postgres (databaseProvider: "postgres") | Use Neon or Supabase - serverless cannot pool to a self-hosted instance, and init/update refuse the pair. See Database |
| Cache | Self-hosted Redis (ioredis) | Use the Upstash provider - see Caching |
| Content API | gitCommit on with config.contentApi.enabled | Disable 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.