Kodokon kodokon.com

The file system: reading and writing with fs/promises

You read and write files with the fs/promises module and build reliable paths thanks to the path module.

8 min · 3 questions

Open this lesson in Kodokon

In 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.

JAVASCRIPT
import { writeFile } from "node:fs/promises";

await writeFile("notes.txt", "First note\n");
console.log("File created!");
writeFile creates the notes.txt file if it doesn't exist, with the text given as the second parameter.

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.

JAVASCRIPT
import { readFile } from "node:fs/promises";

const text = await readFile("notes.txt", "utf8");
console.log(text);
The file's contents arrive as a string, ready to be manipulated.

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.

JAVASCRIPT
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);
The recursive option avoids an error if the data folder already exists.

Knowledge check

Make sure you remember the key points of this lesson.

  1. What does readFile return if you omit the second utf8 parameter?
    • An empty string
    • An error: the encoding is mandatory
    • A Buffer, meaning the raw bytes of the file
  2. What does writeFile do if the target file already exists?
    • It replaces all the existing content with the new text
    • It adds the new text at the end of the file
    • It refuses to write and throws an error
    • It automatically creates a backup copy
  3. What is the benefit of path.join for building a path?
    • It creates the missing folders of the path
    • It assembles the pieces with the right separator for the system
    • It checks that the file exists before continuing