JavaScript course menu
Node.js Basics: Running JavaScript on the Server
Get started with Node.js: what it is and what it is used for, the differences from browser JavaScript, process and command-line arguments, reading and writing files with node:fs/promises, paths, environment variables, and building a tiny HTTP server.
On this page
Node.js runs JavaScript outside the browser, on servers and on your own computer. It uses the same V8 engine as Chrome, plus built-in modules for files, networking and the operating system. It is used for web servers and APIs, command-line tools, build tools, and real-time apps such as chat. Install it as described in Running JavaScript.
Browser JavaScript versus Node.js#
process: information about the running program#
console.log(typeof process.version);
console.log(process.version.startsWith("v"));
console.log(typeof process.cwd());
console.log(["win32", "darwin", "linux"].includes(process.platform));string
true
string
trueThe exact values depend on your computer: process.version is the Node version (such as v24.x.x), process.platform is the operating system and process.cwd() is the current folder.
Command-line arguments#
process.argv holds the words typed after node:
const [, , name = "friend", times = "1"] = process.argv;
for (let i = 0; i < Number(times); i++) {
console.log(`Hello, ${name}!`);
}node greet.js Asha 2Hello, Asha!
Hello, Asha!The first two entries are the paths of node and the script, which is why the destructuring skips them.
Environment variables#
Configuration such as ports and API keys comes from environment variables, read through process.env:
const port = Number(process.env.PORT ?? 3000);
const apiKey = process.env.WEATHER_API_KEY; // never hard-code secretsNode.js 20.6 and later can load a .env file with node --env-file=.env app.js. Never commit .env files containing real secrets to Git.
Files#
The promise-based file API lives in node:fs/promises:
import { writeFile, readFile, appendFile, readdir, mkdir } from "node:fs/promises";
import path from "node:path";
await mkdir("notes", { recursive: true });
const file = path.join("notes", "todo.txt");
await writeFile(file, "Learn Node.js\n");
await appendFile(file, "Build an API\n");
const text = await readFile(file, "utf8");
console.log(text.trim().split("\n"));
console.log(await readdir("notes"));[ 'Learn Node.js', 'Build an API' ]
[ 'todo.txt' ]- Always pass an encoding (
"utf8") toreadFileto get a string; otherwise you get a raw Buffer. - File operations can fail (missing file, no permission), so wrap them in
try...catchin real programs.
JSON files#
import { writeFile, readFile } from "node:fs/promises";
const settings = { theme: "dark", fontSize: 18 };
await writeFile("settings.json", JSON.stringify(settings, null, 2));
const loaded = JSON.parse(await readFile("settings.json", "utf8"));
console.log(loaded.theme, loaded.fontSize);dark 18Paths#
Use node:path instead of joining paths with strings, so the code works on Windows (\) and Linux or macOS (/):
import path from "node:path";
console.log(path.basename("/data/reports/june.csv"));
console.log(path.extname("photo.final.jpeg"));
console.log(path.parse("/data/reports/june.csv").name);june.csv
.jpeg
juneIn ES modules, import.meta.dirname gives the folder of the current file (Node.js 20.11 and later).
A tiny web server#
The built-in node:http module can serve web pages and APIs:
import { createServer } from "node:http";
const courses = [
{ id: 1, name: "HTML" },
{ id: 2, name: "CSS" },
];
const server = createServer((req, res) => {
if (req.method === "GET" && req.url === "/api/courses") {
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(courses));
return;
}
res.writeHead(404, { "Content-Type": "text/plain" });
res.end("Not found");
});
server.listen(3000, () => console.log("Listening on http://localhost:3000"));Run node server.js and open http://localhost:3000/api/courses in your browser to see the JSON. Press Ctrl+C to stop the server.
Real projects usually use a framework such as Express, Fastify or Hono on top of this, which handles routing, request bodies and middleware. Full-stack frameworks such as Next.js combine a Node.js server with a React front end.
Asynchronous by design#
Node.js handles many connections at once on a single thread by never waiting idly: file and network operations are asynchronous, and the event loop runs callbacks as results arrive. Avoid the ...Sync versions of file functions (such as readFileSync) inside servers, because they block every other request while they run. They are fine in small scripts.
Practice#
Practice exercise
Write a script that creates scores.json containing [{ "name": "Asha", "score": 92 }, { "name": "Ravi", "score": 78 }], reads it back, and prints the average score and the name of the top scorer.
Show solution
import { writeFile, readFile } from "node:fs/promises";
const data = [
{ name: "Asha", score: 92 },
{ name: "Ravi", score: 78 },
];
await writeFile("scores.json", JSON.stringify(data));
const scores = JSON.parse(await readFile("scores.json", "utf8"));
const average = scores.reduce((sum, s) => sum + s.score, 0) / scores.length;
const top = scores.reduce((best, s) => (s.score > best.score ? s : best));
console.log("Average:", average);
console.log("Top scorer:", top.name);Average: 85
Top scorer: AshaKey takeaway#
Finished this lesson?