Using the Node.js File System (fs) Module

Working with files is a common task in back-end development. Node.js provides the built-in fs module, which offers a comprehensive set of methods to interact with the file system. From reading and writing files to creating directories and watching file changes, the fs module is a core part of many Node.js applications.

In this article, we’ll explore both synchronous and asynchronous ways to use the fs module effectively.


Table of Contents

  1. What Is the fs Module?
  2. Importing the fs Module
  3. Reading Files
  4. Writing Files
  5. Appending to Files
  6. Deleting Files
  7. Working with Directories
  8. File System Operations: Sync vs Async
  9. Using Promises with fs.promises
  10. Real-World Use Cases
  11. Conclusion

1. What Is the fs Module?

The fs module (short for File System) is a built-in Node.js module that allows developers to work with the file system on your computer. It can be used to:

  • Create, read, update, and delete files (CRUD)
  • Create and manage directories
  • Check file stats and metadata
  • Watch for file changes

2. Importing the fs Module

You can import it using:

const fs = require('fs');

Or, for promise-based APIs:

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

3. Reading Files

Asynchronous Method

fs.readFile('example.txt', 'utf8', (err, data) => {
if (err) {
return console.error(err);
}
console.log(data);
});

Synchronous Method

const data = fs.readFileSync('example.txt', 'utf8');
console.log(data);

4. Writing Files

Asynchronous Method

fs.writeFile('output.txt', 'Hello, Node.js!', (err) => {
if (err) throw err;
console.log('File written successfully!');
});

Synchronous Method

fs.writeFileSync('output.txt', 'Synchronous write!');

5. Appending to Files

fs.appendFile('output.txt', '\nAppended content.', (err) => {
if (err) throw err;
console.log('Content appended!');
});

6. Deleting Files

fs.unlink('output.txt', (err) => {
if (err) throw err;
console.log('File deleted!');
});

7. Working with Directories

Creating a Directory

fs.mkdir('new-folder', (err) => {
if (err) throw err;
console.log('Directory created!');
});

Reading a Directory

fs.readdir('.', (err, files) => {
if (err) throw err;
console.log(files); // Array of file and directory names
});

Deleting a Directory

fs.rmdir('new-folder', (err) => {
if (err) throw err;
console.log('Directory removed!');
});
Note: Use fs.rm or fs.promises.rm with { recursive: true } for non-empty directories in modern Node.js.

8. File System Operations: Sync vs Async

  • Asynchronous functions don’t block the main thread, making them ideal for production environments.
  • Synchronous functions are easier to read but can slow down the application if overused.

Prefer async versions in server-side applications for better performance.


9. Using Promises with fs.promises

Modern Node.js supports using promises with the file system for cleaner, async/await syntax:

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

async function readFileContent() {
try {
const data = await fs.readFile('example.txt', 'utf8');
console.log(data);
} catch (err) {
console.error(err);
}
}
readFileContent();

This approach improves code readability and error handling.


10. Real-World Use Cases

  • Creating log files
  • Processing user-uploaded files
  • Building static site generators
  • Watching changes for live-reload in dev environments
  • Config and temp file management in applications

11. Conclusion

The fs module is a cornerstone of file management in Node.js. Whether you’re manipulating files or building custom tools, mastering both the synchronous and asynchronous methods of fs helps you build robust applications. As you progress, consider leveraging fs.promises with async/await to write cleaner, modern Node.js code.