fs module

Last Updated : Oct 2026


fs module provides a way to interact with the file system in Node.js. It allows you to read, write, and manipulate files on your system.

Almost every backend application interacts with files—whether it's saving configuration settings, storing user uploads, processing logs, or reading static data.

So we are going to cover the following topics:

  1. Promise-based fs operations (modern, clean async/await syntax).
  2. Streams (how to handle large files without blowing up your RAM).

Import the fs module using CommonJS:

const fs = require("node:fs/promises");

Import the fs module using ESM :

import fs from "node:fs/promises";

Promise-based fs operations

In early Node.js, file methods relied on callbacks or synchronous blocking calls (readFileSync). Modern Node gives us clean Promises out of the box via node:fs/promises.

Note: Must wrap inside a try-catch block to handle errors

Some Common methods are:

  • exists(): Checks if a file or directory exists and returns a Promise that resolves with a boolean.If file doesn't exist, it returns false.
import fs from "node:fs"; //not in fs/promises
const exists = await fs.existsS(filePath);
console.log("File exists:", exists);
  • readFile(): Reads a file and returns a Promise that resolves with the contents of the file as a Buffer.if file doesn't exist, it throws an error.

What is a Buffer?

A Buffer is a binary data structure that represents a sequence of bytes(hexadecimal format). It is used to store and manipulate data in memory.

To convert a Buffer to human-readable text: rawData.toString().

try {
  const data = await fs.readFile(filePath, "utf-8");
  console.log(data);
} catch (error) {
  console.error(error);
}

When you read a file without passing an encoding format like 'utf-8' it returns a Buffer object.

  • writeFile(): Writes data to a file and returns a Promise that resolves when the file has been written.If file doesn't exist, it creates a new file.
await fs.writeFile(filePath, "Hello, World!");
console.log("File written successfully!");
  • appendFile(): Appends data to a file and returns a Promise that resolves when the data has been appended.If file doesn't exist, it creates a new file.
await fs.appendFile(filePath, "Hello, World!");
console.log("Data appended successfully!");
  • rename(): Renames a file or directory and returns a Promise that resolves when the file or directory has been renamed.If file doesn't exist, it throws an error.
await fs.rename(oldPath, newPath);
console.log("File renamed successfully!");
  • mkdir(): Creates a directory and returns a Promise that resolves when the directory has been created.If directory already exists, it throws an error.
await fs.mkdir("new-directory");
console.log("Directory created successfully!");

Streams

Streams are a way to handle large files without blowing up your RAM.

Imagine you need to read a 2 GB log file on a server with only 1 GB of free RAM:

  • fs.readFile() loads the entire 2 GB into memory at once →\rightarrow Server crashes (Out of Memory)!
  • Streams read the file chunk by chunk in small pieces (typically 64 KB per chunk) and process them as they arrive.

Types of Streams

  1. Readable: Stream you read from (e.g., reading a video file).
  2. Writable: Stream you write to (e.g., writing output to a file).
  3. Duplex/Transform: Streams that read and write or modify data as it passes through (e.g., zip compression).

Creating a Readable Stream

const readableStream = fs.createReadStream(filePath, { encoding: "utf-8" });

// Listen to individual chunks flowing through
readableStream.on("data", (chunk) => {
  console.log("Received a chunk of data:", chunk.length, "bytes");
});

Creating a Writable Stream

const writableStream = fs.createWriteStream(filePath);

// Write data to the stream
writableStream.write("Hello, World!");
writableStream.end();

Creating a Duplex/Transform Stream

const duplexStream = fs
  .createReadStream(filePath)
  .pipe(fs.createWriteStream("output.txt"));

Examples Of Writing One File Data To Another File

import fs from "node:fs";
import { pipeline } from "node:stream/promises";

// 1. Create a readable stream from a file
const readableStream = fs.createReadStream(filePath, { encoding: "utf-8" });

// 2. Create a writable stream to a new destination file
const writableStream = fs.createWriteStream("output.txt");

// 3. Use pipeline to safely pump data from readable -> writable stream
async function runCopy() {
  try {
    await pipeline(readableStream, writableStream);
    console.log("Stream copy completed successfully!");
  } catch (err) {
    console.error("Pipeline failed:", err);
  }
}

runCopy();

Liked This Tutorial

Scan QR Code To Leave A Review Or

Click Here To Leave A Review
Scan QR