Deploying Node Applications in JavaScript
Introduction
Local node server.mjs is only the first step. Deployment means running your app reliably on a server or platform with the right Node version, environment variables, process manager, and health checks. This chapter outlines a practical path from dev laptop to production—aligned with how many teams ship Node APIs and Next.js apps.
Prerequisites
Production Checklist
- Pin Node LTS version (
.nvmrcor host image) - Set
NODE_ENV=production - Provide secrets via host env, not git
- Run
npm cifrom lockfile (notnpm installon server) - Expose one HTTP port; put TLS on reverse proxy
- Log to stdout; aggregate with host tooling
Build vs Run
Pure Node scripts may have no build step. Bundled apps compile first:
npm ci
npm run build
npm startRead each project’s README—Next.js and Vite differ from a single server.mjs.
Process Manager — PM2 Example
npm install -g pm2
pm2 start index.mjs --name my-api
pm2 save
pm2 startupUseful commands:
pm2 list
pm2 logs my-api
pm2 restart my-apiPM2 restarts crashed processes and supports cluster mode for multi-core.
Reverse Proxy
Run Node on 127.0.0.1:3000; nginx or Caddy forwards public HTTPS:
client → HTTPS → nginx → http://127.0.0.1:3000 → Node appNode app does not need root privileges on port 443.
Health Endpoint
// health route for load balancers
if (url.pathname === "/health") {
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify({ status: "ok", uptime: process.uptime() }));
return;
}Orchestrators ping /health before sending traffic.
Platform Deploy (PaaS)
Services like Railway, Render, Fly.io, or Vercel (for Next.js):
- Connect git repository
- Set build/start commands
- Configure env vars in dashboard
- Deploy on push
Same code—less server admin than raw VPS.
Zero-Downtime Restarts
Rolling deploys start new instances before stopping old ones. With PM2:
pm2 reload my-apiDrain connections using graceful shutdown.
Mini Example: Start Script in package.json
{
"name": "my-api",
"type": "module",
"engines": {
"node": ">=22"
},
"scripts": {
"start": "node server.mjs"
}
}Host reads engines to warn on version mismatch.
FAQ
Docker?
Package app + Node image; pass env at docker run—common in teams but optional for first deploy.
How many instances?
Scale horizontally behind a load balancer when CPU or traffic grows—one process per core is a starting heuristic.
Logs and monitoring?
Ship stdout to your host’s log stack; add APM (Datadog, Sentry) for errors and latency.
What comes next?
Internationalization API and other extension chapters 86–95.