Skip to main content

Supported platforms

The backend is a standard Node.js/Express application and can be deployed to any Node.js hosting provider. Commonly used options include:

Render

Free tier available. Supports automatic deploys from GitHub and managed PostgreSQL databases.

Railway

Simple GitHub-based deploys with built-in PostgreSQL provisioning.

Heroku

Established platform with extensive add-on ecosystem including PostgreSQL.

Deployment steps

1

Provision a PostgreSQL database

Create a PostgreSQL database on your hosting provider and note the connection string. Most providers expose this as a DATABASE_URL environment variable automatically.
Use a managed PostgreSQL service such as Supabase Postgres, Neon, or Railway Postgres to avoid managing your own database server, backups, and upgrades.
2

Set environment variables

Configure the following environment variables in your hosting provider’s dashboard:
VariableDescription
DATABASE_URLPostgreSQL connection string (e.g., postgresql://user:pass@host:5432/db)
JWT_SECRETCryptographically random secret used to sign JWTs
PORTPort the Express server listens on (many providers set this automatically)
NODE_ENVSet to production
3

Run Prisma migrations

Before starting the server, apply migrations to your production database. Run this command as part of your deploy pipeline or release command:
npm run prisma:migrate
This runs prisma migrate dev against the DATABASE_URL in your environment.
4

Start the server

Start the compiled server with:
npm start
This runs node dist/index.js. Alternatively, for development-style deployments without a build step:
npm run dev
This runs tsx watch src/index.ts directly.

Production environment variables

VariableRequiredDescription
DATABASE_URLYesPostgreSQL connection string including credentials and database name
JWT_SECRETYesSecret key for signing and verifying JWTs. Must be a strong, unique random value
PORTNoPort to listen on. Defaults to 5000 if not set. Most platforms set this automatically
NODE_ENVYesSet to production to enable production-mode behavior
Change JWT_SECRET to a cryptographically random value before deploying to production. You can generate one with openssl rand -hex 32. Changing JWT_SECRET invalidates all existing user sessions — every logged-in user will be signed out and must log in again.
The backend enables cors() globally with no origin restrictions. In production, configure the CORS origin to match your Vercel frontend domain to prevent other origins from making authenticated requests to your API. Update backend/src/index.ts to pass an origin option:
app.use(cors({ origin: "https://your-frontend.vercel.app" }))

Build docs developers (and LLMs) love