fs module
The fs module is a core Node.js module that provides an API for interacting with the file system. It supports both synchronous and asynchronous operations, as well as promise‑based variants via fs/promises. Whether you need to read a configuration file, write logs, or recursively scan directories, fs is the go‑to module.
Syntax
const fs = require('fs'); // CommonJS
import fs from 'fs'; // ES modules
import { readFile } from 'fs/promises'; // promise‑based
Parameters
The fs module exports dozens of functions; the most common ones share similar parameter patterns.
| Parameter | Type | Default | Description |
|---|---|---|---|
path | string | (required) | File or directory path. Can be absolute or relative to process.cwd(). |
options | object or string | null | Encoding (e.g., 'utf8') or an object with encoding, flag, etc. |
callback | function | (required for async) | Called with (err, data) when the operation completes. |
mode | integer | 0o666 (files) / 0o777 (dirs) | Permissions for newly created files/directories (octal). |
Examples
Basic usage
Read a text file asynchronously with fs.readFile:
const fs = require('fs');
fs.readFile('notes.txt', 'utf8', (err, data) => {
if (err) {
console.error('Error reading file:', err);
return;
}
console.log('File content:', data);
});
Output (assuming notes.txt contains "Hello from Node.js"):
File content: Hello from Node.js
Write a file synchronously
Use fs.writeFileSync for simple, blocking writes:
const fs = require('fs');
try {
fs.writeFileSync('output.log', 'Log entry at ' + new Date().toISOString());
console.log('File written successfully');
} catch (err) {
console.error('Write failed:', err);
}
Output:
File written successfully
Working with directories
List the contents of a directory with fs.readdir:
const fs = require('fs');
const path = require('path');
const target = './src';
fs.readdir(target, (err, entries) => {
if (err) {
console.error('Cannot read directory:', err);
return;
}
console.log(`Files in ${target}:`);
entries.forEach(entry => {
const fullPath = path.join(target, entry);
const stat = fs.statSync(fullPath);
console.log(` ${entry} (${stat.isDirectory() ? 'dir' : 'file'})`);
});
});
Example output:
Files in ./src:
index.js (file)
utils (dir)
config.json (file)
Common Patterns
Copy a file using streams
For large files, use streams to avoid loading the entire file into memory:
const fs = require('fs');
function copyFile(source, destination) {
const readStream = fs.createReadStream(source);
const writeStream = fs.createWriteStream(destination);
readStream.pipe(writeStream);
writeStream.on('finish', () => {
console.log(`Copied ${source} → ${destination}`);
});
readStream.on('error', (err) => {
console.error('Read error:', err);
});
writeStream.on('error', (err) => {
console.error('Write error:', err);
});
}
copyFile('input.mp4', 'output.mp4');
Recursive directory removal
Node.js ≥ 14 provides fs.rmSync with the recursive option; for older versions you can write a small recursive function.
const fs = require('fs');
const path = require('path');
function rmRecursive(dir) {
if (fs.existsSync(dir)) {
fs.readdirSync(dir).forEach(entry => {
const full = path.join(dir, entry);
if (fs.lstatSync(full).isDirectory()) {
rmRecursive(full);
} else {
fs.unlinkSync(full);
}
});
fs.rmdirSync(dir);
}
}
rmRecursive('./old‑cache');
console.log('Removed ./old‑cache');
See Also
- Stream – Stream-based file processing
- Path – Path manipulation utilities
- FsPromises – Promise-based FS API