Node.js File System Module

The fs module (short for File System) is a built-in Node.js module that provides the ability to work with the file system on the computer. It allows reading from files, writing to files, creating new files, deleting files, renaming files, and working with directories — all from within a Node.js program.

Since the fs module is a core module, no installation is required. It is simply loaded using require('fs').

Loading the fs Module

const fs = require('fs');

Synchronous vs Asynchronous File Operations

The fs module provides two styles of every operation:

  • Synchronous (Sync): The program pauses and waits for the file operation to complete before moving on. Methods have Sync in their name (e.g., readFileSync).
  • Asynchronous (Async): The program does not wait. The operation runs in the background, and a callback function is called when it finishes. This is the recommended approach in Node.js.

For learning purposes, both approaches are shown throughout this topic.

Reading Files

Reading a File Asynchronously

First, create a file called message.txt with some text:

Hello! This is the content of the file.

Now read it in Node.js:

// readFile.js
const fs = require('fs');

fs.readFile('message.txt', 'utf8', function(err, data) {
  if (err) {
    console.log("Error reading file:", err);
    return;
  }
  console.log("File content:", data);
});

Output:

File content: Hello! This is the content of the file.

The second argument 'utf8' tells Node.js to return the content as a readable string. Without it, the raw binary data (Buffer) is returned.

Reading a File Synchronously

const fs = require('fs');

const data = fs.readFileSync('message.txt', 'utf8');
console.log("File content:", data);

This is simpler but blocks everything else while reading. Use synchronously only when absolutely necessary.

Writing Files

Writing to a File (Creates File if It Doesn't Exist)

const fs = require('fs');

const content = "This text is being saved to a file!";

fs.writeFile('output.txt', content, 'utf8', function(err) {
  if (err) {
    console.log("Error writing file:", err);
    return;
  }
  console.log("File saved successfully!");
});

If the file output.txt already exists, its content will be replaced. If it does not exist, it will be created.

Writing Synchronously

const fs = require('fs');

fs.writeFileSync('output.txt', "Hello from writeFileSync!");
console.log("File written!");

Appending to a File

To add content to an existing file without removing what is already there, use appendFile:

const fs = require('fs');

fs.appendFile('output.txt', '\nThis line is appended.', 'utf8', function(err) {
  if (err) {
    console.log("Error appending to file:", err);
    return;
  }
  console.log("Content appended!");
});

Each time this runs, the new line is added to the end of the file. This is useful for logging purposes.

Checking if a File Exists

const fs = require('fs');

fs.access('output.txt', fs.constants.F_OK, function(err) {
  if (err) {
    console.log("File does not exist.");
  } else {
    console.log("File exists.");
  }
});

Renaming a File

const fs = require('fs');

fs.rename('output.txt', 'renamed.txt', function(err) {
  if (err) {
    console.log("Error renaming file:", err);
    return;
  }
  console.log("File renamed successfully!");
});

Deleting a File

const fs = require('fs');

fs.unlink('renamed.txt', function(err) {
  if (err) {
    console.log("Error deleting file:", err);
    return;
  }
  console.log("File deleted successfully!");
});

Working with Directories

Creating a Directory

const fs = require('fs');

fs.mkdir('my-folder', function(err) {
  if (err) {
    console.log("Error creating folder:", err);
    return;
  }
  console.log("Folder created!");
});

To create nested directories (e.g., parent/child/grandchild), use the recursive option:

fs.mkdir('parent/child', { recursive: true }, function(err) {
  if (err) console.log(err);
  else console.log("Nested folders created!");
});

Reading Directory Contents

const fs = require('fs');

fs.readdir('.', function(err, files) {
  if (err) {
    console.log("Error reading directory:", err);
    return;
  }
  console.log("Files and folders in current directory:");
  files.forEach(function(file) {
    console.log(file);
  });
});

Removing a Directory

const fs = require('fs');

fs.rmdir('my-folder', function(err) {
  if (err) console.log(err);
  else console.log("Folder removed!");
});

For removing folders that have content inside them, use:

fs.rm('my-folder', { recursive: true }, function(err) {
  if (err) console.log(err);
  else console.log("Folder and contents removed!");
});

Getting File Information

const fs = require('fs');

fs.stat('message.txt', function(err, stats) {
  if (err) {
    console.log("Error:", err);
    return;
  }
  console.log("Is a file:", stats.isFile());
  console.log("Is a directory:", stats.isDirectory());
  console.log("File size (bytes):", stats.size);
  console.log("Last modified:", stats.mtime);
});

Using fs with Promises (Modern Approach)

Node.js also provides a promise-based version of the fs module, which works well with async/await:

const fs = require('fs').promises;

async function readMyFile() {
  try {
    const data = await fs.readFile('message.txt', 'utf8');
    console.log("File content:", data);
  } catch (err) {
    console.log("Error:", err);
  }
}

readMyFile();

This approach is cleaner and avoids deeply nested callback functions. The async/await syntax is covered in detail in a later topic.

Key Points

  • The fs module is a built-in Node.js module — no installation needed.
  • It provides methods to read, write, append, rename, delete files, and work with directories.
  • Each operation has a synchronous (blocking) and an asynchronous (non-blocking) version.
  • Asynchronous methods are preferred in Node.js as they do not block the execution of other code.
  • The 'utf8' encoding option returns file content as a readable string instead of raw binary.
  • writeFile overwrites existing content; use appendFile to add content without overwriting.
  • The promise-based version of fs (require('fs').promises) pairs cleanly with async/await.

Leave a Comment

Your email address will not be published. Required fields are marked *