You read and write files with the fs/promises module and build reliable paths thanks to the path module.
Open this lesson in KodokonIn the browser, JavaScript isn't allowed to touch the files on your disk: it's a matter of security. Node, on the other hand, runs directly on your machine and can read and write files thanks to the fs module (file system). We'll use its modern version, fs/promises, whose every function returns a promise - you already know how to await them with await, seen in the JavaScript track. Notice the node: prefix in the imports: it makes clear that the module comes from Node itself, not from node_modules. And good news: in an ES module, await works directly at the file level, without an enclosing function.
import { writeFile } from "node:fs/promises";
await writeFile("notes.txt", "First note\n");
console.log("File created!");To read, same logic with readFile. Its second parameter is essential: utf8 designates the encoding, meaning the way of translating the bytes stored on the disk into readable text. If you omit it, Node returns a Buffer object - raw bytes - instead of a string.
import { readFile } from "node:fs/promises";
const text = await readFile("notes.txt", "utf8");
console.log(text);Let's talk paths. A relative path (notes.txt, data/log.txt) starts from the current folder; an absolute path (C:\... or /home/...) starts from the root of the disk. A classic trap: Windows separates folders with \, macOS and Linux with /. The path module solves the problem: path.join assembles the pieces with the right separator, whatever the system. Let's combine it with mkdir, which creates a folder.
import path from "node:path";
import { mkdir, writeFile } from "node:fs/promises";
const file = path.join("data", "log.txt");
await mkdir("data", { recursive: true });
await writeFile(file, "First log\n");
console.log("Written to:", file);