chokidar README

The project's README from github.com/paulmillr/chokidar. As one markdown file: README.md.

Chokidar Weekly downloads

Minimal and efficient cross-platform file watching library

Why?

There are many reasons to prefer Chokidar to raw fs.watch / fs.watchFile in 2026:

Chokidar relies on the Node.js core fs module, but when using fs.watch and fs.watchFile for watching, it normalizes the events it receives, often checking for truth by getting file stats and/or dir contents. The fs.watch-based implementation is the default, which avoids polling and keeps CPU usage down. Be advised that chokidar will initiate watchers recursively for everything within scope of the paths that have been specified, so be judicious about not wasting system resources by watching much more than needed. For some cases, fs.watchFile, which utilizes polling and uses more resources, is used.

Made for Brunch in 2012, it is now used in ~30 million repositories and has proven itself in production environments.

Getting started

Install with npm:

npm install chokidar

Use it in your code:

import chokidar from 'chokidar';

// One-liner for current directory
chokidar.watch('.').on('all', (event, path) => {
  console.log(event, path);
});

// Extended options
// ----------------

// Initialize watcher.
const watcher = chokidar.watch('file, dir, or array', {
  ignored: (path, stats) => stats?.isFile() && !path.endsWith('.js'), // only watch js files
  persistent: true,
});

// Something to use when events are received.
const log = console.log.bind(console);
// Add event listeners.
watcher
  .on('add', (path) => log(`File ${path} has been added`))
  .on('change', (path) => log(`File ${path} has been changed`))
  .on('unlink', (path) => log(`File ${path} has been removed`));

// More possible events.
watcher
  .on('addDir', (path) => log(`Directory ${path} has been added`))
  .on('unlinkDir', (path) => log(`Directory ${path} has been removed`))
  .on('error', (error) => log(`Watcher error: ${error}`))
  .on('ready', () => log('Initial scan complete. Ready for changes'))
  .on('raw', (event, path, details) => {
    // internal
    log('Raw event info:', event, path, details);
  });

// 'add', 'addDir' and 'change' events also receive stat() results as second
// argument when available: https://nodejs.org/api/fs.html#fs_class_fs_stats
watcher.on('change', (path, stats) => {
  if (stats) console.log(`File ${path} changed size to ${stats.size}`);
});

// Watch new files.
watcher.add('new-file');
watcher.add(['new-file-2', 'new-file-3']);

// Get list of actual paths being watched on the filesystem
let watchedPaths = watcher.getWatched();

// Un-watch some files.
await watcher.unwatch('new-file');

// Stop watching. The method is async!
await watcher.close().then(() => console.log('closed'));

// Full list of options. See below for descriptions.
// Do not use this example!
chokidar.watch('file', {
  persistent: true,

  // ignore .txt files
  ignored: (file) => file.endsWith('.txt'),
  // watch only .txt files
  // ignored: (file, _stats) => _stats?.isFile() && !file.endsWith('.txt'),

  awaitWriteFinish: true, // emit single event when chunked writes are completed
  atomic: true, // emit proper events when "atomic writes" (mv _tmp file) are used

  // The options also allow specifying custom intervals in ms
  // awaitWriteFinish: {
  //   stabilityThreshold: 2000,
  //   pollInterval: 100
  // },
  // atomic: 100,

  interval: 100,
  binaryInterval: 300,

  cwd: '.',
  depth: 99,

  followSymlinks: true,
  ignoreInitial: false,
  ignorePermissionErrors: false,
  usePolling: false,
  alwaysStat: false,
});

chokidar.watch(paths, [options])

Persistence

Path filtering

Performance

Errors

Methods & Events

chokidar.watch() produces an instance of FSWatcher. Methods of FSWatcher:

CLI

Check out third party chokidar-cli, which allows to execute a command on each change, or get a stdio stream of change events.

Troubleshooting

Sometimes, Chokidar runs out of file handles, causing EMFILE and ENOSP errors:

There are two things that can cause it.

  1. Exhausted file handles for generic fs operations
    • Can be solved by using graceful-fs, which can monkey-patch native fs module used by chokidar: let fs = require('fs'); let grfs = require('graceful-fs'); grfs.gracefulify(fs);
    • Can also be solved by tuning OS: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p.
  2. Exhausted file handles for fs.watch
    • Can't seem to be solved by graceful-fs or OS tuning
    • It's possible to start using usePolling: true, which will switch backend to resource-intensive fs.watchFile

All fsevents-related issues (WARN optional dep failed, fsevents is not a constructor) are solved by upgrading to v4+.

Changelog

Upgrading

If you've used globs before and want do replicate the functionality with v4:

// v3
chok.watch('**/*.js');
chok.watch('./directory/**/*');

// v4
chok.watch('.', {
  ignored: (path, stats) => stats?.isFile() && !path.endsWith('.js'), // only watch js files
});
chok.watch('./directory');

// other way
import { glob } from 'node:fs/promises';
const watcher = watch(await Array.fromAsync(glob('**/*.js')));

// unwatching
// v3
chok.unwatch('**/*.js');
// v4
chok.unwatch(await Array.fromAsync(glob('**/*.js')));

Also

Why was chokidar named this way? What's the meaning behind it?

Chowkidar is a transliteration of a Hindi word meaning 'watchman, gatekeeper', चौकीदार. This ultimately comes from Sanskrit _ चतुष्क_ (crossway, quadrangle, consisting-of-four). This word is also used in other languages like Urdu as (چوکیدار) which is widely used in Pakistan and India.

License

MIT (c) Paul Miller (https://paulmillr.com), see LICENSE file.

chokidar (paulmillr/chokidar)

Searching Database…

12.2K ·GitHub
这是什么?Chokidar 是一个精简、高效的跨平台文件监听库,适用于 Node.js。它能把操作系统原生文件系统 API 产生的杂乱事件,统一整理成清晰的 add、change 和 unlink 事件。
这是我要导入的库,还是自带命令行工具?它是通过 npm 安装、在代码中调用 chokidar.watch() 使用的 Node.js 库。如果你想要命令行工具,可以使用单独的第三方包 chokidar-cli,但它不属于核心包的一部分。
我该怎么开始监听文件?先用 npm 安装,然后调用 chokidar.watch(paths, [options]),传入一个路径或路径数组,再使用 .on(event, callback) 监听事件(如 add、change、unlink 等)。
它依赖什么?它基于 Node 的核心模块 fs 构建。从 v4 开始,它只剩一个外部依赖(readdirp),而较早版本有 13 个。
它还支持像 watch('*.js') 这样的 glob 通配符模式吗?不支持了。glob 支持在 v4 中随内置的 fsevents 二进制文件一起被移除,所以现在你需要在传入路径之前,自行展开所有 glob 模式。
它在 macOS、Linux 和 Windows 上的表现一样吗?基本一样。但 macOS 通过原生的 fsevents 后端能获得更丰富的事件(直接报告文件名)。对于网络驱动器等特殊情况,你可能需要强制使用 usePolling,而不是依赖原生的 fs.watch。
为什么叫 chokidar?它的名字源自印地语/乌尔都语单词 'chowkidar'(चौकीदार),意为守望者或门卫。这个词可以追溯到梵语中的“十字路口”一词。
最新的 v5 版本有什么变化?v5 于 2025 年 11 月发布,它把该包改为仅支持 ESM,并将最低支持的 Node.js 版本提高到 v20。
它能处理分块写入的文件,或编辑器原子方式保存的文件吗?可以。awaitWriteFinish 会轮询文件大小,直到写入停止,以处理分块保存;atomic 选项默认开启,会把某些编辑器使用的“先删除再重建”模式合并为一次 change 事件。
chokidar 实际上有多广泛的使用?它最初是 2012 年从 Brunch 构建工具中提取出来的,现在大约有 3000 万个代码仓库在使用它。
What are similar projects?tsx, core-js, upm, Inquirer.js, ua-parser-js, joi, node, tsdx
Creator
paulmillr
Size
2.1 MB
Stars
12.2K
Age
14y
Commits · 90 Days