Node.js Quickstart
Deploy a small Node.js HTTP application as a NexHost Web Service.
Node.js Quickstart#
This quickstart deploys a small HTTP application as a Web Service. NexHost discovers its reachable TCP listener and assigns ingress automatically, so the application must start a persistent server bound to 0.0.0.0.
Use Frontend App instead for a server-rendered Next.js, Nuxt, Remix, or SvelteKit UI. The contract is the same — start a server bound to 0.0.0.0 — but the frontend service exists so your UI and backend can have separate hostnames and build/start semantics while both using the public-runtime model.
When to use this quickstart#
Use this page when:
- The deliverable is a public Node backend — Express, Fastify, Koa, NestJS, or a lightweight
httpserver — that should answer browser, mobile, and webhook callers over a hostname. - You want a five-minute sanity check that your application’s startup shape is correct before you connect a larger repository.
Skip this quickstart when:
- The deliverable is a server-rendered frontend — use the Frontend App flow, where
next start -p $PORTis the launchable. - The deliverable is pre-built static files only — use Static Site.
Before you begin#
- Node.js 18+ locally (for local verification).
- A NexHost workspace and permission to create a project.
- A few minutes on the command line — the guide intentionally avoids tooling magic so the dashboard values match what you just typed.
Create the application#
From an empty parent directory:
mkdir my-node-app && cd my-node-app
npm init -y
npm install expressCreate index.js at the project root:
const express = require("express");
const app = express();
const port = Number(process.env.PORT);
app.get("/", (_request, response) => response.send("Hello from NexHost"));
app.get("/health", (_request, response) => response.status(200).json({ ok: true }));
app.listen(port, "0.0.0.0", () => {
console.log(`Listening on ${port}`);
});Why this shape:
Number(process.env.PORT)reads NexHost's compatibility default (3000). A fixed internal port is also safe because NexHost discovers the listener and assigns the external port.- Binding to
"0.0.0.0"attaches to the container’s network interface, not only to loopback. Binding only to"127.0.0.1"makes the runtime observe "connection refused" even when your localhostcurlsucceeded. /healthis optional application monitoring; NexHost readiness is based on TCP reachability rather than this route.
Set the start script in package.json:
{ "scripts": { "start": "node index.js" } }Verify locally before you deploy:
```bash
PORT=3000 npm start &
curl -i http://127.0.0.1:3000/health
# expect 200 with {"ok": true} quickly, no authentication required
```
Configure the service#
- In New Project, select Web Service — not Frontend App, not Static Site.
- Choose a supported source and connect this project — a repository checkout, ZIP archive, or local folder. Confirm the branch and root directory when offered.
- Set Start command to
npm start. The dashboard already knows the install and build commands needed for most Node projects; if you customized them locally, mirror those values here. - Deploy and open the generated hostname shown by the dashboard after the release becomes ready.
The server must bind to 0.0.0.0. It may use process.env.PORT or a fixed internal port; NexHost discovers it automatically.
Do not place secrets in client-inlined variables for a frontend that shares this workspace. A service-scoped secret should not be given a browser-exposed prefix just because another service is a static site.
What success looks like#
- The deployment detail page shows the process log line "Listening on <PORT>" and a TCP-readiness confirmation.
- The service’s generated hostname at the dashboard loads
Hello from NexHostat/and{"ok": true}at/health— both without passing a cookie or header. - Future environment variable changes on this service apply at the next deployment or re-launched process, depending on whether they were scoped to Build or Runtime.
Troubleshooting#
| Symptom | What to check |
|---|---|
| Startup readiness times out | Is npm start the start command rather than npm run build (which exits immediately)? Does the server bind to 0.0.0.0 and reach its listen call? |
| Connection refused | Binding only to 127.0.0.1 is the classic variant. |
| Build succeeds but process exits quickly | The start command built rather than ran — move the build step to Build and keep a continuous start mechanism in Start. |
See Deployment Troubleshooting for the full symptom table and Logs for reading each stage’s output.
Related documentation#
- Web Services — full public-runtime contract for Node backends.
- Frontend Apps — the analogous flow for server-rendered frontends.
- Environment Variables — when to scope a key to Build vs Runtime vs Both.
- Domains and Networking — public hostnames, custom domains, and the
PORTcontract.