The fs (file system) module lets Node.js interact with files and directories.

Importing fs

  // Callback-based (legacy)
const fs = require('fs');

// Promise-based (recommended)
const fs = require('fs/promises');

// ES modules
import fs from 'fs/promises';
import { readFileSync } from 'fs';
  

Reading Files

  import fs from 'fs/promises';

// Async/await
const content = await fs.readFile('data.txt', 'utf-8');
console.log(content);

// With error handling
try {
    const data = await fs.readFile('config.json', 'utf-8');
    const config = JSON.parse(data);
} catch (err) {
    if (err.code === 'ENOENT') {
        console.error('File not found');
    }
}
  

Writing Files

  import fs from 'fs/promises';

await fs.writeFile('output.txt', 'Hello, Node.js!', 'utf-8');

// Append to file
await fs.appendFile('log.txt', 'New log entry\n');
  

Working with Directories

  import fs from 'fs/promises';
import path from 'path';

// Create directory
await fs.mkdir('uploads', { recursive: true });

// List directory contents
const files = await fs.readdir('./src');
console.log(files);

// Check if path exists
try {
    await fs.access('./config.json');
    console.log('File exists');
} catch {
    console.log('File does not exist');
}

// Get file stats
const stats = await fs.stat('data.txt');
console.log(stats.isFile());    // true
console.log(stats.size);        // bytes
console.log(stats.mtime);       // last modified
  

Copy, Move, Delete

  await fs.copyFile('source.txt', 'dest.txt');
await fs.rename('old-name.txt', 'new-name.txt');
await fs.unlink('delete-me.txt');       // delete file
await fs.rm('temp-dir', { recursive: true }); // delete directory
  

Watching Files

  import fs from 'fs';

fs.watch('config.json', (eventType, filename) => {
    console.log(`${eventType}: ${filename}`);
});
  

Path Utilities

Always use path for cross-platform paths:

  import path from 'path';

path.join('users', 'alice', 'profile.json');
// 'users/alice/profile.json' (or backslashes on Windows)

path.resolve('./config', 'app.json');
path.extname('photo.jpg');  // '.jpg'
path.basename('/users/alice/file.txt'); // 'file.txt'
  

Practical Example: JSON Config Loader

  import fs from 'fs/promises';
import path from 'path';

async function loadConfig(env = 'development') {
    const configPath = path.join(process.cwd(), 'config', `${env}.json`);
    const data = await fs.readFile(configPath, 'utf-8');
    return JSON.parse(data);
}

const config = await loadConfig();
console.log(config.port);
  

Use fs/promises with async/await for clean, readable file operations.