Install Chokidar via npm
mainTo use Chokidar in your project, install it using npm:
npm install chokidarrepository·main·Indexed 11 days ago
https://github.com/paulmillr/chokidarA minimal and efficient cross-platform file watching library for Node.js. It provides a consistent API for monitoring file system events, handling atomic writes, and recursive watching. Version 5.0.0 includes an FSWatcher instance for managing paths via .add(), .unwatch(), and .close(), and supports advanced configuration options like awaitWriteFinish for large file writes and custom path filtering via the ignored option.
To use Chokidar in your project, install it using npm:
npm install chokidarIn version 4, Chokidar removed built-in glob support. If your code relies on glob patterns (e.g., **/*.js), you must migrate to one of the following two patterns:
ignored optionWatch a directory and use the ignored function to filter for specific file extensions or patterns.
node:fs/promises globsUse the native Node.js glob function to resolve paths first, then pass the resulting array of paths to chokidar.watch().
Note on Unwatching: Because globs are no longer supported, you cannot call unwatch() with a glob string. You must resolve the glob to an array of paths first and pass that array to unwatch().
// v3 (Old way - Glob support included)
chok.watch('**/*.js');
chok.unwatch('**/*.js');
// v4 (New way - Option 1: Using ignored function)
chok.watch('.', {
ignored: (path, stats) => stats?.isFile() && !path.endsWith('.js'),
});
// v4 (New way - Option 2: Using native Node.js globs)
import { glob } from 'node:fs/promises';
const watcher = chok.watch(await Array.fromAsync(glob('**/*.js')));
// v4 (New way - Unwatching with resolved paths)
chok.unwatch(await Array.fromAsync(glob('**/*.js')));The chokidar.watch method accepts an options object to fine-tune behavior.
persistent (default: true): Whether the process should continue running as long as files are being watched.ignored: A function, regex, or path defining what to ignore. If a function is used, it receives (path, stats). The entire path is tested.ignoreInitial (default: false): If true, add/addDir events are not emitted for existing files during the initial scan.followSymlinks (default: true): Whether to follow symbolic links.cwd (no default): The base directory for deriving watch paths. Emitted paths will be relative to this.usePolling (default: false): Uses fs.watchFile (polling) instead of fs.watch. Set to true for watching files over a network.interval (default: 100): Polling interval in ms (used when usePolling is true).binaryInterval (default: 300): Polling interval for binary files.alwaysStat (default: false): If true, ensures fs.Stats is passed to add, addDir, and change events even if not provided by the OS.depth (default: undefined): Limits how many levels of subdirectories are traversed.awaitWriteFinish (default: false): If true, waits for a file size to remain constant for a stabilityThreshold (default 2000ms) before emitting add/change events. Useful for large/chunked writes.ignorePermissionErrors (default: false): If true, suppresses EPERM or EACCES errors.atomic (default: true if not using useFsEvents or usePolling): Filters out artifacts from editors using atomic writes. If a file is re-added within 100ms of being deleted, it emits change instead of unlink + add. You can set this to a custom millisecond value.The ignored option accepts a Matcher, which can be one of the following types:
(val: string, stats?: Stats) => boolean that returns true if the path should be ignored.{ path: 'some/path', recursive: true }If Chokidar runs out of file handles, you may see EMFILE or ENOSPC errors.
graceful-fs to monkey-patch the native fs module:let fs = require('fs');
let grfs = require('graceful-fs');
grfs.gracefulify(fs);echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
### Exhausted file handles for `fs.watch`
- If `graceful-fs` and OS tuning do not work, switch to polling by setting `usePolling: true` in your Chokidar options.
You can start watching the current directory with a single line of code. The all event emits every file system event along with its path.
import chokidar from 'chokidar';
// One-liner for current directory
chokidar.watch('.').on('all', (event, path) => {
console.log(event, path);
});An FSWatcher instance provides methods to dynamically update what is being watched:
.add(path | paths): Add a single path or an array of paths to the watcher..unwatch(path | paths): Stop watching specific files or directories..getWatched(): Returns an object where keys are directory paths and values are arrays of filenames currently being watched..close(): Asynchronous. Removes all listeners and stops watching. Always await this method to prevent bugs.const watcher = chokidar.watch('some-dir');
// Add new files to watch
watcher.add('new-file.txt');
watcher.add(['file2.txt', 'file3.txt']);
// Get current watched paths
let watchedPaths = watcher.getWatched();
// Stop watching specific files
await watcher.unwatch('new-file.txt');
// Stop the watcher entirely
await watcher.close();The chokidar.watch(paths, [options]) method returns an FSWatcher instance. You can listen to specific events like add, change, and unlink to react to file system changes.
add: File addedaddDir: Directory addedchange: File changedunlink: File removedunlinkDir: Directory removedready: Initial scan completeerror: Watcher errorall: Emits all events (except ready, raw, and error) as (event, path)raw: Internal raw event info (use with caution)import chokidar from 'chokidar';
const watcher = chokidar.watch('path/to/watch', { persistent: true });
watcher
.on('add', (path) => console.log(`File ${path} added`))
.on('change', (path, stats) => console.log(`File ${path} changed`))
.on('unlink', (path) => console.log(`File ${path} removed`))
.on('ready', () => console.log('Ready for changes'));When calling watch(paths, options), you can provide a ChokidarOptions object to customize watcher behavior.
persistent: (boolean) Whether to keep the watcher running. Defaults to true.ignoreInitial: (boolean) Whether to ignore existing files when the watcher starts. Defaults to false.followSymlinks: (boolean) Whether to follow symbolic links. Defaults to true.cwd: (string) The current working directory for relative paths.usePolling: (boolean) Whether to use polling instead of native OS events. Defaults to false (except on IBM i).interval: (number) Polling interval in milliseconds. Defaults to 100.binaryInterval: (number) Polling interval for binary files. Defaults to 300.atomic: (boolean | number) Enables atomic write normalization. If a number, it specifies the delay in milliseconds. Defaults to true (or !usePolling).ignorePermissionErrors: (boolean) Whether to ignore errors like EPERM or EACCES. Defaults to false.depth: (number) Maximum depth to watch.alwaysStat: (boolean) Whether to always provide Stats objects with events.ignored: (Matcher | Matcher[]) A string, RegExp, function, or MatcherObject used to filter out paths.awaitWriteFinish: (boolean | Partial<AWF>) If true, the watcher waits for a file to stop changing in size before emitting an event. If an object, you can configure:stabilityThreshold: (number) Milliseconds the file size must remain constant. Defaults to 2000.pollInterval: (number) How often to check the file size. Defaults to 100.To prevent emitting events before a file has finished being written (e.g., during a large copy operation), use the awaitWriteFinish option. The watcher will poll the file and only emit the add or change event once the file size remains stable for the specified stabilityThreshold.
const watcher = watch('.', {
awaitWriteFinish: {
stabilityThreshold: 3000,
pollInterval: 200
}
});import { watch } from 'chokidar';
const watcher = watch('.', {
awaitWriteFinish: {
stabilityThreshold: 3000,
pollInterval: 200
}
});The FSWatcher instance provides methods to manage what is being watched during its lifecycle:
add(paths: Path | Path[]): Adds new paths to the existing watcher. Returns the FSWatcher instance for chaining.unwatch(paths: Path | Path[]): Stops watching specified paths and ignores future events from them. Returns the FSWatcher instance for chaining.close(): Returns a Promise that resolves when all watchers are closed and all listeners are removed.const watcher = watch('src');
// Later, add more paths
watcher.add(['test', 'docs']);
// Stop watching a specific directory
watcher.unwatch('src/temp');
// Shut down the watcher
await watcher.close();Use the watch function to create an FSWatcher instance that monitors file system changes. You can pass a single string or an array of strings representing the paths to watch. The function returns an FSWatcher instance, which supports method chaining.
Common events to listen for include add, addDir, change, unlink, unlinkDir, all, and error.
import { watch } from 'chokidar';
// Basic usage
const watcher = watch('.').on('all', (event, path) => {
console.log(event, path);
});
// Usage with options
const watcherWithOpts = watch('.', {
atomic: true,
awaitWriteFinish: true,
ignored: (f, stats) => stats?.isFile() && !f.endsWith('.js')
});