watchexec: Run a Command on File Changes
watchexec monitors the current directory and runs a given command whenever a matching file changes, debouncing rapid edits and respecting .gitignore.
watchexec is for the local edit-run loop: tests on save, a server that restarts on change. It runs until you stop it, so it is not a CI step.
What it does
watchexec watches the filesystem and re-runs the command you pass each time a tracked file changes. It debounces bursts of events, ignores .gitignore-d paths, and can restart a long-running process (-r) by killing the previous run before starting the next.
Common usage
watchexec -e py pytest # run tests when .py files change
watchexec -e rs -r -- cargo run # restart the app on Rust changes
watchexec -w src -w lib npm test # watch specific directories
watchexec --debounce 500ms make build # wait 500ms after the last changeOptions
| Flag | What it does |
|---|---|
| -e / --exts <list> | Only react to these comma-separated extensions |
| -w / --watch <path> | Watch a specific path (repeatable) |
| -r / --restart | Kill and restart the command on each change |
| --debounce <dur> | Wait this long after the last event before running |
| -i / --ignore <pat> | Ignore paths matching the glob |
| --on-busy-update <mode> | queue, restart, or do-nothing while still running |
| -c / --clear | Clear the screen before each run |
In CI
watchexec is interactive and long-lived, so it does not belong in a CI step: it never exits and would hang the job. Reserve it for local development. If you need a one-shot "run on change" inside an ephemeral environment, you almost certainly want a normal build step or a Makefile target instead.
Common errors in CI
A CI job that "never finishes" after a watchexec call is working as designed: it is waiting for changes forever; remove it from the pipeline. "watchexec: command not found" (install via cargo install watchexec-cli, brew install watchexec, or a release binary). Nothing triggering on edits usually means the changed file is .gitignore-d or outside the watched -w path.