Node.js runs JavaScript on the server. It is the engine behind a huge share of today's APIs, real-time apps and build tools, and it lets one team use one language from the browser to the database. This guide takes you through the ideas that matter, from the event loop to production, with short, current code examples you can run as they are.
Install the current LTS release of Node.js (Node.js 24 in September 2026), use ES modules and async/await, and lean on what is now built in: fetch, the node:test runner, --watch and --env-file. Build web APIs with a framework such as Express 5, keep secrets in environment variables, and run production apps behind a process manager or on a platform that restarts them. On Domain India, small apps can run on shared hosting through the control panel's Node.js tool; production apps fit the App Platform or a VPS.
1. What Node.js is, and what it is good at
Node.js is a JavaScript runtime built on Google's V8 engine. Instead of starting a new thread for every request, it runs your code on one main thread and hands slow work, such as reading files, querying a database or calling another API, to the operating system. When that work finishes, Node.js runs the code waiting for the result.
This makes Node.js very good at:
- APIs and web back ends that spend most of their time waiting on databases and other services;
- real-time apps such as chat, dashboards and notifications over WebSockets;
- tooling: bundlers, linters and command-line tools.
It is a weaker fit for long, CPU-heavy calculations such as video encoding, because heavy work on the main thread blocks every other request. Section 8 covers how to handle that.
2. Install Node.js and choose a version
Node.js releases a new major version every six months. Even-numbered versions become LTS (long-term support) and are the ones to use in production. In September 2026 the Active LTS line is Node.js 24; Node.js 22 is in maintenance, and Node.js 20 reached end of life in April 2026.
Install it with a version manager so you can switch between projects: see installing Node.js and npm on your local machine and working with Node.js versions using nvm. Check what you have:
node --version
npm --version3. The event loop and asynchronous code
Everything slow in Node.js is asynchronous. Modern code uses promises with async/await, which reads like ordinary step-by-step code:
import { readFile } from 'node:fs/promises';
async function loadConfig() {
const text = await readFile('config.json', 'utf8');
return JSON.parse(text);
}
const config = await loadConfig(); // top-level await works in ES modules
console.log(config);While readFile waits on the disk, the event loop keeps serving other work. Older code uses callbacks (fs.readFile(path, (err, data) => …)); you will still meet them, but prefer the node:fs/promises and other promise-based APIs in new code.
Synchronous calls such as readFileSync inside a request handler, or a long loop over a large array, stop the whole server from answering anyone until they finish. Use the async versions in request paths and move heavy computation to a worker thread.
4. Modules and npm
New projects should use ES modules (import/export). Add "type": "module" to package.json:
mkdir my-api && cd my-api
npm init -y
npm pkg set type=module
npm install expressCommit package-lock.json, install exactly what it lists in CI and production with npm ci, and run npm audit regularly. More detail is in understanding modules and npm in Node.js.
5. Files, streams and buffers
For small files, readFile is fine. For large files or network data, use streams, which process data piece by piece so memory stays flat:
import { createReadStream, createWriteStream } from 'node:fs';
import { createGzip } from 'node:zlib';
import { pipeline } from 'node:stream/promises';
await pipeline(
createReadStream('access.log'),
createGzip(),
createWriteStream('access.log.gz')
);pipeline handles errors and closes every stream, which the older .pipe() chain does not. A Buffer holds raw bytes, for example Buffer.from('hello', 'utf8'), and is what streams pass around underneath.
6. Build an HTTP API with Express
Node.js has a built-in node:http module, but most APIs use a framework. Express 5 is the current major version and handles errors thrown in async route handlers for you:
import express from 'express';
const app = express();
app.use(express.json());
app.get('/api/items', async (req, res) => {
res.json({ items: ['apple', 'banana'] });
});
app.post('/api/items', async (req, res) => {
const { name } = req.body ?? {};
if (typeof name !== 'string' || name.length > 100) {
return res.status(400).json({ error: 'name is required' });
}
res.status(201).json({ name });
});
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Listening on ${port}`));Reading the port from PORT matters: most hosting platforms tell your app which port to use this way. Other good frameworks include Fastify, Hono and NestJS for larger, structured codebases.
Real-time features use WebSockets. Libraries such as Socket.IO or ws attach to the same HTTP server; check that your hosting supports long-lived WebSocket connections before you rely on them.
7. Databases
Use a maintained driver or query builder, and always pass values as parameters, never by joining strings:
import mysql from 'mysql2/promise';
const pool = mysql.createPool(process.env.DATABASE_URL);
const [rows] = await pool.query(
'SELECT id, name FROM customers WHERE email = ?',
[email]
);For PostgreSQL, use pg; for a typed schema and migrations, an ORM such as Prisma or Drizzle. The older mysql package is no longer the right choice; use mysql2. Parameterised queries are the main defence against SQL injection; see preventing SQL injection.
8. Errors, testing and debugging
- Errors. Wrap
awaitcalls intry/catchwhere you can do something useful, and let a central error handler return a clean 500 for the rest. LogunhandledRejectionanduncaughtException, then let the process exit and be restarted; carrying on after an unknown error leaves the app in an unknown state. - Testing. Node.js has a built-in test runner, so small projects need no extra package:
// sum.test.js (run with: node --test)
import { test } from 'node:test';
import assert from 'node:assert/strict';
test('adds numbers', () => {
assert.equal(1 + 2, 3);
});Vitest and Jest remain popular for larger front-end-heavy projects.
- Debugging. Run
node --inspect server.jsand attach VS Code or Chrome DevTools, or use the editor's built-in Node.js debugger. Usenode --watch server.jsto restart automatically while you edit. - CPU-heavy work. Move it to
node:worker_threads, or to a separate job queue, so the main thread keeps answering requests.
9. Configuration and security
- Keep secrets in environment variables, never in code.
node --env-file=.env server.jsloads a local.envfile without extra packages; add.envto.gitignore. - Validate every input, use HTTPS, set security headers (the
helmetmiddleware does this for Express), and rate-limit login routes. - Keep dependencies current and remove the ones you don't use.
The OWASP Top 10 practical defence guide covers the rest.
10. Running Node.js in production
A production app needs something to start it, restart it when it crashes, and put HTTPS in front of it. On your own server that is usually PM2 or systemd behind a reverse proxy such as nginx or Caddy; see PM2 process management. On a platform, the platform does it for you. Build any TypeScript or front-end assets before deploying, run with NODE_ENV=production, and log to standard output so the platform can collect the logs.
11. Running this on Domain India
| Option | Good for | What to know |
|---|---|---|
| cPanel or DirectAdmin shared hosting | Small apps and APIs | Create the app in the panel's Node.js tool. On cPanel we measured Node.js 20, 22 and 24; choose 24. Not for background workers or long-running jobs |
| App Platform | Most production Node.js apps | Node.js is detected automatically from package.json; deploy from GitHub with Deploy Now or with a deploy token; PostgreSQL included; no SSH |
| VPS | Full control, several services, your own databases | Self-managed with root access: you install Node.js, PM2 or systemd and a reverse proxy |
Two limits to know on shared hosting: MongoDB Atlas cannot be reached from our shared servers, because its port is not open outbound, so use MySQL or PostgreSQL there, or run MongoDB-backed apps on the App Platform or a VPS. And jailed SSH is available on every shared plan but is off by default; ask support to enable it.
Guides: deploy a Node.js app on shared hosting, getting started with the App Platform and the Node.js handbook.
- 512 MB RAM per app
- 1 vCPU
- 5 GB NVMe SSD
- PostgreSQL Database
To go further with full-stack projects, see building a chat application with the MERN stack and user authentication with OAuth 2.0. Support is on 24/7 live chat, and tickets get a first response within 15 minutes; there is no phone support.
Which Node.js version should I use in 2026?
Use the current Active LTS release, which is Node.js 24 in September 2026. Node.js 22 is still supported in maintenance, and Node.js 20 reached end of life in April 2026, so move projects off it.
Should I use require or import?
Use import. ES modules are the standard for new Node.js projects; add "type": "module" to package.json. You will still meet require in older code and packages.
Is Node.js single-threaded?
Your JavaScript runs on one main thread, while slow input and output is handled by the operating system in the background. For CPU-heavy work, use worker threads so the main thread stays free to answer requests.
Do I still need Jest or nodemon?
Not for small projects. Node.js has a built-in test runner (node --test) and a watch mode (node --watch). Larger projects often still use Vitest or Jest.
Can I run a Node.js app on Domain India shared hosting?
Yes, small apps run through the Node.js tool in cPanel or DirectAdmin. For production apps, background workers or anything needing more control, use the App Platform or a VPS.
Can I connect to MongoDB Atlas from shared hosting?
No. The MongoDB port is not open outbound on Domain India shared servers. Use MySQL or PostgreSQL on shared hosting, or run the app on the App Platform or a VPS.
Does the App Platform detect Node.js apps automatically?
Yes. It detects a Node.js app from package.json and builds it. Your app must listen on the PORT environment variable and bind to 0.0.0.0.
Ready to ship your app? Compare App Platform plans, run a small app on cPanel hosting, or choose a VPS if you want to manage the server yourself.
Deploy from GitHub or with a deploy token, with PostgreSQL and free SSL included in every plan.
See App Platform plans