~/
Working with Files
Quiz
...

Working with Files

beginner · updated Tue Sep 22 2026Contribute

Read and write files with the promise-based fs API.

Working with Files

Node can read and write files on your machine. The modern API lives in node:fs/promises and returns promises you can await.

Reading a File

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

const text = await readFile("notes.txt", "utf8");
console.log(text);

Always pass an encoding like "utf8". Without it you get a Buffer of raw bytes.

Writing a File

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

await writeFile("out.txt", "Hello, file!", "utf8");

writeFile replaces the whole file. To append instead:

import { appendFile } from "node:fs/promises";

await appendFile("log.txt", "new line\n");

Checking and Removing

import { access, mkdir, rm } from "node:fs/promises";

await access("config.json");          // throws if missing
await mkdir("data", { recursive: true }); // create nested dirs safely
await rm("old.txt", { force: true });     // delete, ignore if absent

Building Paths

Never join paths with "/" — Windows uses "\\". Use node:path:

import path from "node:path";

const file = path.join("content", "posts", "hello.md");
const abs = path.resolve(file);

import.meta.dirname gives the current file’s folder in ESM:

const data = path.join(import.meta.dirname, "data.json");

Handling Errors

File operations can fail. Catch and handle:

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

try {
  const config = await readFile("config.json", "utf8");
  console.log(JSON.parse(config));
} catch (err) {
  if (err.code === "ENOENT") {
    console.error("config.json not found");
  } else {
    throw err;
  }
}

Big Files: Streams

readFile loads everything into memory. For large files, stream them:

import { createReadStream } from "node:fs";

const stream = createReadStream("big.log");
stream.on("data", (chunk) => process.stdout.write(chunk));

Best Practices

  1. Use node:fs/promises — Avoid callback-style fs.
  2. Use node:path — Cross-platform paths, always.
  3. Set an encoding"utf8" for text.
  4. Stream large files — Do not buffer gigabytes in memory.

Common Mistakes

  1. Assuming the file exists — Wrap in try/catch.
  2. String-concatenating paths — Breaks on Windows.
  3. Forgetting await — You get a pending Promise, not the content.
  4. Using relative paths carelessly — They resolve from the process’s working directory.