Deploy/Express
Framework guide

Deploy a Express app to production

Express is still the API layer agents write for anything Node that isn't Next.js. It's a long-running server by design, which makes it an awkward fit for function platforms and a trivial one for Launchmatic.

How detection works

A package.json with a start script (Nixpacks uses it directly). TypeScript projects also need a build script (tsc) — detected and run automatically.

Build configuration & gotchas

Port binding

app.listen(process.env.PORT || 3000) — agents get this right most of the time; the one that bites is binding to localhost instead of 0.0.0.0 (omit the host argument and Node binds all interfaces).

TypeScript

Ensure "build": "tsc" and "start": "node dist/index.js". Running via ts-node in production works but wastes memory; Nixpacks will use whatever your scripts say.

Health endpoint

Add a GET /health returning 200 — Launchmatic uses it for readiness checks so deploys only cut over when the new pod is actually serving.

Environment variables

DATABASE_URLInjected when you link a Postgres; works with pg/Prisma/Drizzle as-is.
NODE_ENVSet to `production` automatically.

The three lines that make any Express app deploy-ready:

const port = process.env.PORT || 3000;
app.get("/health", (_req, res) => res.sendStatus(200));
app.listen(port, () => console.log(`listening on ${port}`));

FAQ

Can I run Express with WebSockets (socket.io)?+

Yes — socket.io, ws, and SSE all work because your app is one persistent process. No sticky-session gymnastics needed on a single replica; for multiple replicas, add the standard Redis adapter.

Ready to deploy?

Free to start. No credit card. Auto-SSL on custom domains, managed Postgres, and per-branch preview deploys included.

This guide is part of our complete vibe coding hosting guide — how to take any AI-built app to production.

AI tools that emit this stack