Skip to content
Latchkey

watchexec: Usage, Options & Common CI Errors

watchexec re-runs a command whenever watched files change.

watchexec is a file-watcher for local dev loops. The CI hazard is obvious once stated: it is a long-running watcher, so invoking it in a pipeline hangs the job until timeout.

What it does

watchexec monitors a directory tree for changes and runs (or restarts) a command in response. It respects .gitignore by default and can filter by extension or path, making it a fast local feedback loop.

Common usage

Terminal
watchexec -- cargo test
watchexec -e ts,tsx -- npm run build
watchexec -w src -- ./run.sh                    # watch a specific dir
watchexec -r -- node server.js                  # restart on change
watchexec --exts py --debounce 500ms -- pytest

Options

FlagWhat it does
-e / --exts <list>Only react to these file extensions
-w / --watch <path>Watch a specific path (repeatable)
-r / --restartRestart the command instead of waiting
--debounce <dur>Coalesce rapid changes into one run
-i / --ignore <glob>Ignore matching paths
-1 / --onceRun once then exit (no watching)

Common errors in CI

watchexec never exits on its own - it watches forever - so a CI step that calls it stalls until the job timeout kills it. It is a dev tool: do not put a bare watchexec in a pipeline. If you only want to run the command once, use the underlying command directly (or watchexec -1). On headless runners with no inotify capacity you may see "too many open files" / "inotify watch limit reached"; raise fs.inotify.max_user_watches.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →