The fs module
Browsers cannot touch your files. Node can, through the built-in fs (file system) module.
const fs = require("node:fs"); fs.writeFileSync("notes.txt", "hello"); // create or overwrite const text = fs.readFileSync("notes.txt", "utf8"); // read as text
The Sync suffix means blocking: the whole thread stops until the disk answers. Fine for a startup script, bad inside a busy server (lesson 2-2 told you why). The non-blocking versions take a callback:
fs.readFile("notes.txt", "utf8", (err, data) => { if (err) return console.error("could not read"); console.log(data); });
Note the error-first callback: Node convention puts a possible error as the first argument, the result second. Always check err before touching data.
Code exercise · javascript
Run this visit counter. It writes a file, reads it back, adds one, and saves it again. This is the simplest form of persistence, data that survives after the code finishes.
The process object
Every Node program gets a global process object describing the running program:
process.argv: the command-line arguments (node app.js --port 4000).process.env: environment variables, key-value settings from the outside world. This is how servers receive secrets and config (unit 8 builds on it).process.stdin: the standard input stream, text piped into your program.
process.stdin is a stream that fires callbacks as data arrives, the same event style servers use for incoming requests:
let input = ""; process.stdin.on("data", (chunk) => { input += chunk; }); process.stdin.on("end", () => { // all input has arrived, use it here });
.on(name, callback) means "when the name event happens, run this". You will meet .on again the moment we open a real HTTP server in unit 3.
Code exercise · javascript
Run this. The Input box below the editor feeds process.stdin, exactly like a terminal pipe would. The "end" callback fires once all input has arrived.
Quiz
In fs.readFile(path, "utf8", (err, data) => {...}), why does the callback receive err as the FIRST argument?
Code exercise · javascript
Your turn. Implement readConfig(path, callback) using fs.readFile with an error-first callback: on error call callback(err, null), on success call callback(null, data). The calls at the bottom must print "config: port=3000" and then "no config file".