Node.js

File System

Work with files and directories in Node.js using the fs module with both callback and promise APIs.

Reading Files

Node.js provides the fs module for file system operations. The modern fs/promises API is the recommended approach.

import { readFile, readdir, stat } from 'fs/promises';
import { createReadStream } from 'fs';
import path from 'path';

// Read entire file
async function readConfig(filename: string): Promise<object> {
  const filepath = path.join(process.cwd(), 'config', filename);
  const content = await readFile(filepath, 'utf-8');
  return JSON.parse(content);
}

// List directory contents
async function listFiles(dir: string): Promise<string[]> {
  const entries = await readdir(dir, { withFileTypes: true });
  return entries
    .filter(entry => entry.isFile())
    .map(entry => entry.name);
}

// Get file info
async function getFileInfo(filepath: string) {
  const stats = await stat(filepath);
  return {
    size: stats.size,
    created: stats.birthtime,
    modified: stats.mtime,
    isFile: stats.isFile(),
    isDirectory: stats.isDirectory(),
  };
}

// Stream large files (memory efficient)
function streamFile(filepath: string): Promise<string> {
  return new Promise((resolve, reject) => {
    const chunks: Buffer[] = [];
    const stream = createReadStream(filepath);

    stream.on('data', chunk => chunks.push(Buffer.from(chunk)));
    stream.on('end', () => resolve(Buffer.concat(chunks).toString()));
    stream.on('error', reject);
  });
}

Writing & Managing Files

Writing files, creating directories, and managing file system paths are common Node.js tasks.

import { writeFile, appendFile, mkdir, rm, copyFile, rename } from 'fs/promises';
import { existsSync } from 'fs';
import path from 'path';

// Write a file (creates or overwrites)
async function saveConfig(data: object, filename: string): Promise<void> {
  const content = JSON.stringify(data, null, 2);
  await writeFile(filename, content, 'utf-8');
  console.log(`Saved ${filename}`);
}

// Append to a log file
async function log(message: string): Promise<void> {
  const timestamp = new Date().toISOString();
  const entry = `[${timestamp}] ${message}\n`;
  await appendFile('app.log', entry, 'utf-8');
}

// Create nested directories
async function ensureDir(dirPath: string): Promise<void> {
  await mkdir(dirPath, { recursive: true }); // Creates parent dirs too
}

// Safe file operations with error handling
async function safeWriteFile(filepath: string, content: string): Promise<boolean> {
  try {
    const dir = path.dirname(filepath);
    await mkdir(dir, { recursive: true });
    await writeFile(filepath, content, 'utf-8');
    return true;
  } catch (error) {
    console.error(`Failed to write ${filepath}:`, error);
    return false;
  }
}

// Move/rename files
async function moveFile(src: string, dest: string): Promise<void> {
  await ensureDir(path.dirname(dest));
  await rename(src, dest);
}

Always use path.join() or path.resolve() when building file paths to ensure cross-platform compatibility between Windows and Unix systems.