Node.js › File System (fs) Module

How do you safely watch a directory or file for changes using fs.watch(), and what are its known cross-platform limitations?

Intermediate

Answer

fs.watch() emits events ('change', 'rename') when the watched file or directory is modified, but its behavior is notoriously inconsistent across operating systems -- the specific event types fired, whether filenames are always provided, and whether changes are reported reliably or occasionally missed/duplicated all vary between Linux (inotify), macOS (FSEvents), and Windows (ReadDirectoryChangesW), which is why many production tools (like nodemon) instead use a polling-based or hybrid approach, or a dedicated cross-platform library like chokidar, for more predictable behavior.
const fs = require('node:fs');

const watcher = fs.watch('./config', { recursive: true }, (eventType, filename) => {
  console.log(`${eventType} detected on ${filename}`);
  reloadConfig();
});

// For more reliable cross-platform behavior, many teams use chokidar instead:
// const chokidar = require('chokidar');
// chokidar.watch('./config').on('change', reloadConfig);
Real-world example A configuration hot-reload feature that worked reliably in development on macOS started missing some file-change events once deployed to a Linux-based Docker container using a mounted volume; the team switched to chokidar, which handles these platform and virtual-filesystem inconsistencies more robustly than the raw fs.watch() API.

Common follow-ups: Why do file changes inside a Docker volume sometimes behave differently with fs.watch() than changes on a native filesystem?;What's the difference between a polling-based and an event-based file watching strategy in terms of reliability versus resource usage?