chokidar-cli vs gulp-watch vs nodemon
File Watching and Development Process Management
chokidar-cligulp-watchnodemonSimilar Packages:

File Watching and Development Process Management

nodemon, chokidar-cli, and gulp-watch handle file system events but target different layers of the development workflow. nodemon focuses on restarting Node.js processes automatically when source code changes. chokidar-cli provides a generic command-line interface to trigger arbitrary shell commands upon file changes. gulp-watch integrates file watching directly into Gulp task streams, primarily for legacy Gulp 3 pipelines or specific streaming needs.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
chokidar-cli00-05 years agoMIT
gulp-watch0637-708 years agoMIT
nodemon026,697219 kB122 months agoMIT

File Watching and Development Process Management Compared

When building modern web applications, keeping your development environment in sync with file changes is essential. nodemon, chokidar-cli, and gulp-watch all listen for file system events, but they solve different problems. Let's compare how they handle process management, configuration, and integration.

🔄 Core Mechanism: Process Restart vs Command Trigger vs Stream Integration

nodemon wraps your Node.js process and restarts it when files change.

  • It kills the old process and starts a new one automatically.
  • Best for server-side development where the runtime needs to reload.
# nodemon: Restarts the node process
nodemon src/index.js

chokidar-cli watches files and runs a shell command when changes occur.

  • It does not manage the process lifecycle of your app.
  • Best for triggering builds, tests, or linters independently.
# chokidar-cli: Runs a command on change
chokidar 'src/**/*.js' -c 'npm run build'

gulp-watch integrates file watching into a Gulp task stream.

  • It triggers Gulp tasks when files change within a pipeline.
  • Best for legacy Gulp 3 workflows requiring stream-based processing.
// gulp-watch: Triggers a Gulp task
var watch = require('gulp-watch');
watch('src/**/*.js', function() {
  gulp.run('build');
});

⚙️ Configuration Style: JSON vs CLI Args vs JS Pipeline

nodemon uses a nodemon.json file or command-line flags.

  • You can define ignored files, extensions, and environment variables.
  • Configuration is stored separately from your build logic.
// nodemon: nodemon.json
{
  "watch": ["src"],
  "ext": "js,json",
  "ignore": ["src/tests"]
}

chokidar-cli relies entirely on command-line arguments.

  • You pass patterns and commands directly when running the tool.
  • No separate config file is required, though you can script it in npm.
# chokidar-cli: CLI arguments
chokidar 'src/**/*.css' -c 'npm run css:build' --initial

gulp-watch is configured within your gulpfile.js.

  • Watching logic lives alongside your task definitions.
  • Requires JavaScript setup for every watch instance.
// gulp-watch: gulpfile.js
var watch = require('gulp-watch');
watch('src/**/*.html', { verbose: true }, function() {
  // Task logic here
});

🛡️ Error Handling and Stability

nodemon keeps your server running even if code crashes.

  • If your app throws an error on startup, nodemon waits for changes to retry.
  • Prevents the need to manually restart after every syntax error.
# nodemon: Auto-retries on crash
# No extra code needed – handles crashes by waiting for next file save

chokidar-cli runs the command regardless of previous success.

  • If your build command fails, it will run again on the next change.
  • Does not protect your running application from breaking.
# chokidar-cli: Runs command blindly
# If 'npm run build' fails, it just logs error and waits for next change

gulp-watch depends on the Gulp stream error handling.

  • Errors in the pipeline must be caught within the Gulp tasks.
  • Can stop the watch process if errors are not handled properly in the stream.
// gulp-watch: Error handling in stream
watch('src/**/*.js')
  .on('error', function(err) {
    console.error(err.message);
    this.emit('end'); // Prevent watch from stopping
  });

🌐 Real-World Scenarios

Scenario 1: Developing a Node.js API

You are building an Express server and need to see changes immediately.

  • Best choice: nodemon
  • Why? It restarts the server process so new routes or logic load instantly.
# Usage
nodemon server.js

Scenario 2: Compiling Sass to CSS

You need to compile stylesheets when .scss files change.

  • Best choice: chokidar-cli
  • Why? You just need to run a build command, not restart a server.
# Usage
chokidar 'styles/**/*.scss' -c 'npm run sass:build'

Scenario 3: Legacy Build Pipeline

You are maintaining an old Gulp 3 project with complex stream tasks.

  • Best choice: gulp-watch
  • Why? It fits into the existing stream-based task architecture.
// Usage
watch('src/**/*.js', function() {
  gulp.run('lint', 'bundle');
});

📌 Summary Table

Featurenodemonchokidar-cligulp-watch
Primary Goal🔄 Restart Node.js process🚀 Run shell commands🛠️ Trigger Gulp tasks
Config Location📄 nodemon.json or CLI💻 CLI arguments only📝 gulpfile.js
Process Mgmt✅ Handles restarts❌ Runs command only❌ Triggers stream
Best For🖥️ Backend API dev🎨 Asset building🕰️ Legacy Gulp 3
Modern AlternativeN/A (Still standard)Native chokidarNative gulp.watch()

💡 Final Recommendation

nodemon is the standard tool for Node.js server development. Use it when your main goal is to keep a running application up to date with code changes. It saves time by handling process restarts automatically.

chokidar-cli is the right choice for running build steps, linters, or tests when files change. It is lightweight and does not interfere with your application's process lifecycle.

gulp-watch should only be used for maintaining older Gulp 3 projects. For new Gulp 4 projects, use the built-in gulp.watch() function instead. It offers better performance and native support without extra dependencies.

Final Thought: Pick the tool that matches your workflow layer. Use nodemon for the server, chokidar-cli for assets, and avoid gulp-watch unless you are stuck on legacy pipelines.

How to Choose: chokidar-cli vs gulp-watch vs nodemon

  • chokidar-cli:

    Choose chokidar-cli when you need a simple, standalone tool to run shell commands whenever files change. It is ideal for triggering build scripts, linting, or testing without managing the application process itself. This tool works well in mixed environments where you are not solely running a Node.js server.

  • gulp-watch:

    Choose gulp-watch only if you are maintaining a legacy Gulp 3 pipeline that requires specific streaming behavior not covered by native watchers. For new projects using Gulp 4, prefer the built-in gulp.watch() method instead. This package is best reserved for older codebases where upgrading the build system is not currently feasible.

  • nodemon:

    Choose nodemon when developing Node.js servers or APIs that need to restart automatically upon code changes. It handles process lifecycle management, ensuring your server reflects the latest code without manual intervention. This is the standard choice for backend development where process stability and quick reloads are critical.

README for chokidar-cli

Chokidar CLI

Build Status

Fast cross-platform command line utility to watch file system changes.

The underlying watch library is Chokidar, which is one of the best watch utilities for Node. Chokidar is battle-tested:

It is used in brunch, gulp, karma, PM2, browserify, webpack, BrowserSync, socketstream, derby, and many others. It has proven itself in production environments.

Prerequisites

  • Node.js v8.10.0 or newer

Install

If you need it only with npm scripts:

npm install chokidar-cli

Or globally

npm install -g chokidar-cli

Usage

Chokidar can be invoked using the chokidar command, without the -cli suffix.

Arguments use the form of runtime flags with string parameters, delimited by quotes. While in principal both single and double quotes are supported by chokidar-cli, the actual command line argument parsing is dependent on the operating system and shell used; for cross-platform compatibility, use double quotes (with escaping, if necessary), as single quotes are not universally supported by all operating systems.

This is particularly important when using chokidar-cli for run scripts specified in package.json. For maximum platform compatibility, make sure to use escaped double quotes around chokidar's parameters:

"run": {
  "chokidar": "chokidar \"**/*.js\" -c \"...\""
},

Default behavior

By default chokidar streams changes for all patterns to stdout:

$ chokidar "**/*.js" "**/*.less"
change:test/dir/a.js
change:test/dir/a.less
add:test/b.js
unlink:test/b.js

Each change is represented with format event:relativepath. Possible events: add, unlink, addDir, unlinkDir, change.

Output only relative paths on each change

$ chokidar "**/*.js" "**/*.less" | cut -d ":" -f 2-
test/dir/a.js
test/dir/a.less
test/b.js
test/b.js

Run npm run build-js whenever any .js file changes in the current work directory tree

chokidar "**/*.js" -c "npm run build-js"

Watching in network directories must use polling

chokidar "**/*.less" -c "npm run build-less" --polling

Pass the path and event details in to your custom command

chokidar "**/*.less" -c "if [ '{event}' = 'change' ]; then npm run build-less -- {path}; fi;"

Detailed help

Usage: chokidar <pattern> [<pattern>...] [options]

<pattern>:
Glob pattern to specify files to be watched.
Multiple patterns can be watched by separating patterns with spaces.
To prevent shell globbing, write pattern inside quotes.
Guide to globs: https://github.com/isaacs/node-glob#glob-primer


Options:
  -c, --command           Command to run after each change. Needs to be
                          surrounded with quotes when command contains spaces.
                          Instances of `{path}` or `{event}` within the command
                          will be replaced by the corresponding values from the
                          chokidar event.
  -d, --debounce          Debounce timeout in ms for executing command
                                                                  [default: 400]
  -t, --throttle          Throttle timeout in ms for executing command
                                                                  [default: 0]
  -s, --follow-symlinks   When not set, only the symlinks themselves will be
                          watched for changes instead of following the link
                          references and bubbling events through the links path
                                                      [boolean] [default: false]
  -i, --ignore            Pattern for files which should be ignored. Needs to be
                          surrounded with quotes to prevent shell globbing. The
                          whole relative or absolute path is tested, not just
                          filename. Supports glob patterns or regexes using
                          format: /yourmatch/i
  --initial               When set, command is initially run once
                                                      [boolean] [default: false]
  -p, --polling           Whether to use fs.watchFile(backed by polling) instead
                          of fs.watch. This might lead to high CPU utilization.
                          It is typically necessary to set this to true to
                          successfully watch files over a network, and it may be
                          necessary to successfully watch files in other non-
                          standard situations         [boolean] [default: false]
  --poll-interval         Interval of file system polling. Effective when --
                          polling is set                          [default: 100]
  --poll-interval-binary  Interval of file system polling for binary files.
                          Effective when --polling is set         [default: 300]
  --verbose               When set, output is more verbose and human readable.
                                                      [boolean] [default: false]
  --silent                When set, internal messages of chokidar-cli won't be
                          written.                    [boolean] [default: false]
  -h, --help              Show help                                    [boolean]
  -v, --version           Show version number                          [boolean]

Examples:
  chokidar "**/*.js" -c "npm run build-js"  build when any .js file changes
  chokidar "**/*.js" "**/*.less"            output changes of .js and .less
                                            files

License

MIT