RepoPilotOpen in app →

watchexec/cargo-watch

Watches over your Cargo project's source.

Healthy

Healthy across all four use cases

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • 10 active contributors
  • CC0-1.0 licensed
  • CI configured
Show all 6 evidence items →
  • Tests present
  • Stale — last commit 1y ago
  • Concentrated ownership — top contributor handles 78% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/watchexec/cargo-watch)](https://repopilot.app/r/watchexec/cargo-watch)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/watchexec/cargo-watch on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: watchexec/cargo-watch

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/watchexec/cargo-watch shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across all four use cases

  • 10 active contributors
  • CC0-1.0 licensed
  • CI configured
  • Tests present
  • ⚠ Stale — last commit 1y ago
  • ⚠ Concentrated ownership — top contributor handles 78% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live watchexec/cargo-watch repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/watchexec/cargo-watch.

What it runs against: a local clone of watchexec/cargo-watch — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in watchexec/cargo-watch | Confirms the artifact applies here, not a fork | | 2 | License is still CC0-1.0 | Catches relicense before you depend on it | | 3 | Default branch 8.x exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 509 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>watchexec/cargo-watch</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of watchexec/cargo-watch. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/watchexec/cargo-watch.git
#   cd cargo-watch
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of watchexec/cargo-watch and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "watchexec/cargo-watch(\\.git)?\\b" \\
  && ok "origin remote is watchexec/cargo-watch" \\
  || miss "origin remote is not watchexec/cargo-watch (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(CC0-1\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"CC0-1\\.0\"" package.json 2>/dev/null) \\
  && ok "license is CC0-1.0" \\
  || miss "license drift — was CC0-1.0 at generation time"

# 3. Default branch
git rev-parse --verify 8.x >/dev/null 2>&1 \\
  && ok "default branch 8.x exists" \\
  || miss "default branch 8.x no longer exists"

# 4. Critical files exist
test -f "src/main.rs" \\
  && ok "src/main.rs" \\
  || miss "missing critical file: src/main.rs"
test -f "src/watch.rs" \\
  && ok "src/watch.rs" \\
  || miss "missing critical file: src/watch.rs"
test -f "src/args.rs" \\
  && ok "src/args.rs" \\
  || miss "missing critical file: src/args.rs"
test -f "src/options.rs" \\
  && ok "src/options.rs" \\
  || miss "missing critical file: src/options.rs"
test -f "src/rustc.rs" \\
  && ok "src/rustc.rs" \\
  || miss "missing critical file: src/rustc.rs"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 509 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~479d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/watchexec/cargo-watch"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

cargo-watch is a command-line tool that monitors your Rust project's source code for changes and automatically re-runs Cargo commands (like cargo check, cargo test, cargo build) whenever files are modified. It wraps the watchexec library (v1.17.2) and integrates with cargo_metadata to provide intelligent file filtering and build awareness specific to Cargo projects. Single-binary architecture: src/main.rs is the entry point, src/args.rs and src/options.rs parse CLI arguments via clap v2, src/watch.rs contains the core watch loop using the watchexec library, src/rustc.rs handles Rust compiler output parsing, and src/root.rs manages the Cargo project root detection. The binary is built from [[bin]] section in Cargo.toml targeting a single cargo-watch executable.

👥Who it's for

Rust developers who want faster feedback loops during active development—similar to how nodemon or guard work in Node.js and Ruby. Developers who repeatedly run cargo check or cargo test during coding sessions benefit most from the automatic re-invocation without manual shell commands.

🌱Maturity & risk

This project is on life support and not actively developed. The maintainer (@passcod) explicitly states in the README that Cargo Watch will not receive updates but remains available. No recent commits are visible in the file structure, the test suite exists (tests/ with insta snapshots), and CI is configured (check.yml), but the project is superseded by Bacon and Watchexec for new features. It is production-ready but stagnant.

Single-maintainer abandonment risk is extremely high—the README explicitly acknowledges the project is on life support with no planned updates. Dependency count is moderate (watchexec, cargo_metadata, clap 2.34.0 which is quite old, dotenvy, notify-rust), and clap v2 is unmaintained (v4 is current). No breaking changes are expected, but security updates to dependencies may lag. If you depend on this for critical workflows, plan to migrate to Bacon or Watchexec.

Active areas of work

No active development is occurring. The project is frozen at version 8.5.3. The maintainer recommends users migrate to Bacon instead. The GitHub workflows (release.yml, check.yml) are configured but likely dormant. No open PRs or new commits are implied by the file structure.

🚀Get running

git clone https://github.com/watchexec/cargo-watch.git
cd cargo-watch
cargo build --release
cargo run -- -x test

Daily commands:

cargo watch -x check
cargo watch -x test
cargo watch -c -x build

Run cargo watch --help for all options. The tool runs the Cargo subcommand specified after -x whenever watched files change.

🗺️Map of the codebase

  • src/main.rs — Entry point that orchestrates argument parsing, logging setup, and the main watch loop—all contributors must understand the execution flow.
  • src/watch.rs — Core watch loop logic that binds to watchexec library and handles file change events; critical for understanding how cargo commands are triggered.
  • src/args.rs — Command-line argument definitions using clap; essential for understanding the CLI surface and what features are exposed.
  • src/options.rs — Conversion from clap args to internal Options struct; bridges CLI layer with application logic.
  • src/rustc.rs — Handles rustc output parsing and error filtering; critical for the core feature of watching Cargo builds.
  • Cargo.toml — Dependency manifest including watchexec, cargo_metadata, and notify-rust; defines the external integrations.

🧩Components & responsibilities

  • CLI Parser (args.rs + options.rs) (clap, dotenvy (.env support)) — Validates user input, applies defaults, converts clap structs to internal Options.
    • Failure mode: Invalid flags or missing required args → early error and help text; invalid UTF-8 paths → panic.
  • Watch Loop (watch.rs) (watchexec, cargo_metadata, std::process) — Owns the main event loop; detects FS changes, filters by ignore rules, spawns cargo commands.
    • Failure mode: Cargo command fails → output printed; watchexec crashes → whole process exits; killed child process → retries on next event.
  • Rustc Output Parser (rustc.rs) (regex, serde_json (implicit)) — Parses JSON or plain text compiler diagnostics; extracts errors and warnings for display.
    • Failure mode: Malformed rustc output → falls back to raw echo; parsing errors → logged but not fatal.
  • Project Root Detection (root.rs) (cargo_metadata, camino (UTF-8 paths)) — Finds Cargo.toml and workspace structure; determines which paths to watch.
    • Failure mode: No Cargo.toml found → error and exit; workspace misconfigured → may watch wrong paths.
  • Notifications (notify-rust integration) (notify-rust, dbus (Linux) / NSUserNotificationCenter (macOS)) — Optional desktop alert on build completion (especially failures).
    • Failure mode: Notification daemon unavailable → silently skipped; no impact on watch loop.

🔀Data flow

  • File Systemwatchexec — FS events (inotify/FSEvents/ReadDirectoryChangesW) → watchexec debounces and filters by ignore rules
  • watchexecWatch Loop — Debounced change notification triggers cargo command execution
  • Watch LoopCargo Process — Spawns child process with cargo command (check/test/build) and inherits stdio
  • Cargo ProcessRustc Output Parser — Compiler output streamed to parser; errors/warnings extracted and re-formatted
  • Rustc Output ParserTerminal / Desktop Notification — Formatted diagnostics printed to stderr/stdout; optional desktop alert sent
  • cargo_metadataWatch Loop — Project structure (workspaces, source dirs) determines which paths to monitor

🛠️How to make changes

Add a new cargo-watch CLI flag

  1. Define the new argument struct field in the Opt struct with clap attributes (src/args.rs)
  2. Add corresponding field to Options struct and implement conversion logic from Opt (src/options.rs)
  3. Use the new option in the watch loop or command building logic (src/watch.rs)
  4. Add integration tests if the flag affects user-visible behavior (tests/echo.rs)

Enhance rustc output parsing for new diagnostics

  1. Add pattern matching or parsing logic to handle new compiler output format (src/rustc.rs)
  2. Test the new parsing with snapshot tests if output formatting changes (tests/snapshots)

Modify the watch loop behavior or command execution

  1. Implement the new behavior in the main watch event handler (src/watch.rs)
  2. Update Options struct if new configuration is needed (src/options.rs)
  3. Add an exec test to verify the new behavior (tests/exec.rs)

🔧Why these technologies

  • watchexec — Battle-tested file-watching library that handles cross-platform FS events, debouncing, and ignore patterns (gitignore, custom filters).
  • cargo_metadata — Provides structured access to Cargo workspace and package metadata without parsing JSON manually.
  • clap 2.x — Lightweight CLI argument parser; clap 2 chosen for stability over newer 3.x/4.x (backward compatibility during maintenance mode).
  • notify-rust — Desktop notifications (optional); alerts user to build failures without requiring terminal focus.
  • stderrlog & log — Structured logging with verbosity control; keeps internal debug info separate from watched command output.

⚖️Trade-offs already made

  • Watches Cargo.toml + src/, not arbitrary paths

    • Why: Simplifies logic and aligns with typical Rust project structure.
    • Consequence: Users cannot easily watch non-source files (e.g., assets) without custom shell commands.
  • Runs cargo commands sequentially, not in parallel

    • Why: Avoids resource contention and keeps output clear and readable.
    • Consequence: Slow commands (e.g., full cargo test) will delay subsequent triggers.
  • Maintenance mode: no major feature additions

    • Why: Author recommends Bacon or Watchexec as better alternatives.
    • Consequence: Users seeking advanced features should migrate; cargo-watch remains stable but not cutting-edge.

🚫Non-goals (don't propose these)

  • Does not provide IDE-level integration or LSP support
  • Does not run commands in parallel or with concurrency control
  • Does not persist build cache across machine restarts or CI systems
  • Does not modify source code or apply automatic fixes; only re-runs cargo
  • Does not support Windows subsystem details beyond watchexec's built-in support

⚠️Anti-patterns to avoid

  • Blocking command execution in main loop (Medium)src/watch.rs: Cargo commands run synchronously, blocking the watch loop. Long-running tests will prevent new file-change events from being processed until completion.
  • Clap 2.x (obsolete version)Cargo.toml: clap 2.34.0 is end-of-life; project is in maintenance mode and cannot easily upgrade without breaking changes.

🪤Traps & gotchas

No environment setup required, but be aware: clap v2 has significantly different ergonomics than clap v4; migration would be substantial. The maintainer notes the project has 'four different syntaxes' for running commands, which implies legacy complexity in src/args.rs. The watchexec v1.17.2 dependency is somewhat dated (v2+ exists but not used). Tests use insta snapshots (tests/snapshots/*.snap files)—modifying output requires regenerating snapshots with insta review.

🏗️Architecture

💡Concepts to learn

  • File system event notification (inotify/FSEvents) — cargo-watch's entire value proposition depends on efficiently detecting file changes via the watchexec library, which uses OS-native notification APIs (inotify on Linux, FSEvents on macOS, etc.); understanding this avoids polling filesystem constantly
  • Cargo metadata integration — cargo_metadata 0.18.1 is used to query Cargo.toml, understand project structure, and identify which files to watch; modifying src/root.rs requires understanding this crate
  • Rustc compiler output parsing (error/warning format) — src/rustc.rs parses the structured error output from rustc to filter, format, and display compiler messages intelligently; this drives the user-facing formatting
  • Process spawning and signal handling — src/watch.rs spawns Cargo subprocesses and must handle signals (SIGINT, SIGTERM) gracefully; the watchexec crate abstracts this, but understanding process lifecycle is essential for debugging hangs or incomplete shutdowns
  • Desktop notification integration (notify-rust) — notify-rust 4.7.0 sends system notifications (macOS/Linux) when builds complete; this is optional but affects user experience and requires understanding async event handling
  • Snapshot testing with insta — The test suite uses insta 1.32.0 for snapshot-based regression testing (see tests/snapshots/*.snap); modifying output requires understanding snapshot approval workflow, not traditional assertions
  • watchexec/watchexec — The underlying library that cargo-watch wraps for file system notification and command execution; moving to this directly gives more control and modern features
  • bacon-rs/bacon — Modern, actively maintained alternative recommended by the cargo-watch maintainer in the README; adds TUI, task files, and pager support that cargo-watch never got
  • rust-lang/cargo — Cargo itself; cargo-watch integrates via cargo_metadata 0.18.1 to understand project structure and invoke build commands correctly
  • notify-rs/notify — The file system notification library used transitively by watchexec; cargo-watch's performance and reliability depend on this crate's maturity
  • clap-rs/clap — CLI argument parser (v2.34.0); cargo-watch's argument parsing and help text generation depend entirely on clap's definition in src/args.rs

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add integration tests for watch.rs command execution and file watching behavior

The tests/ directory currently only has echo.rs and exec.rs tests with snapshots. The core watch.rs module lacks dedicated integration tests for file watching triggers, debouncing, and command execution chains. This would improve reliability and prevent regressions in the core watching mechanism.

  • [ ] Create tests/watch.rs with integration tests for file modification detection
  • [ ] Add test cases for debouncing behavior in tests/watch.rs
  • [ ] Add test cases for multiple command execution in sequence in tests/watch.rs
  • [ ] Create corresponding snapshot files in tests/snapshots/ for expected outputs
  • [ ] Test interaction between src/watch.rs and src/args.rs argument parsing

Add shell completion tests and verification for zsh completions

The completions/zsh file exists but has no automated tests. Given that cargo-watch is installed via package managers and users rely on shell completions, this is a high-value gap. No test infrastructure exists to validate completion script syntax or coverage of CLI flags.

  • [ ] Create tests/completions.rs to parse and validate zsh completion syntax
  • [ ] Cross-reference completions/zsh against src/args.rs to ensure all flags are documented
  • [ ] Add CI step in .github/workflows/check.yml to validate completion scripts
  • [ ] Verify that new flags added to src/args.rs trigger completion updates
  • [ ] Consider adding bash/fish completion tests in the same test file

Add tests for src/rustc.rs error parsing and output handling

The rustc.rs module handles compiler error parsing and formatting but has no dedicated tests. This is critical since incorrect parsing could cause watch to miss real compilation errors or crash on unexpected rustc output formats across different Rust versions.

  • [ ] Create tests/rustc.rs with unit tests for error parsing functions in src/rustc.rs
  • [ ] Add test cases for various rustc error formats (warnings, errors, notes)
  • [ ] Test handling of multi-line error messages and stack traces
  • [ ] Add snapshot tests in tests/snapshots/ for formatted error output
  • [ ] Test compatibility with the MSRV (Rust 1.75.0) rustc output format

🌿Good first issues

  • Add snapshot tests for src/rustc.rs error parsing: The file has parsing logic but tests/snapshots/ currently only covers echo and exec behavior. Add test cases for actual rustc error/warning output parsing to ensure the formatter handles edge cases.: medium
  • Document the 'four different syntaxes' mentioned in README: Audit src/args.rs to identify and document the multiple command syntaxes (e.g., -x, shell variants, etc.) in a new doc/SYNTAX.md file with examples. The README hints at this pain point but provides no clarity.: small
  • Add integration test for Cargo project detection: src/root.rs finds the Cargo project root, but there's no test in tests/ validating this behavior with nested or non-standard project layouts. Create tests/root.rs with test fixtures in tests/touchdata/.: medium

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 58e792b — 8.5.3 (passcod)
  • e50ab24 — have i not suffered enough (passcod)
  • ed0a943 — use macos-latest (passcod)
  • 2673bba — use watchexec github (passcod)
  • e0174d9 — update snapshots (passcod)
  • 6c2431c — do not fail fast (passcod)
  • 01d3fd2 — bump msrv (passcod)
  • 5d3cd7c — add instructions for pm2/systemd-run (passcod)
  • 2cfce3c — nope, do it here (passcod)
  • 080ab44 — recommend watchexec too (passcod)

🔒Security observations

The cargo-watch codebase has a generally reasonable security posture for a command-line utility. The primary concern is the use of outdated clap dependency (2.34.0) which is no longer maintained. Secondary concerns include proper validation of user input before shell execution and appropriate restrictions on file system monitoring scope. The project uses legitimate security-focused dependencies (shell-escape, dotenvy for .env handling) but these should be paired with robust input validation. No hardcoded credentials, SQL injection risks, or Docker/infrastructure issues were identified in the provided files.

  • Medium · Outdated clap Dependency — Cargo.toml - dependencies section. The codebase uses clap version 2.34.0, which is significantly outdated. clap 2.x reached end-of-life and is no longer maintained. Current versions are clap 3.x and 4.x. Outdated dependencies may contain unpatched security vulnerabilities. Fix: Upgrade clap to the latest version (4.x). Review the migration guide at https://github.com/clap-rs/clap/blob/master/CHANGELOG.md and update code accordingly.
  • Low · Potential Command Injection via shell-escape — src/ - likely in args.rs, options.rs, or watch.rs. The codebase uses shell-escape (0.1.5) to escape shell arguments. While this library exists for this purpose, the use of shell escaping indicates command execution. If user input is improperly validated before reaching shell-escape, injection attacks are possible. Fix: Ensure all user input from command-line arguments is properly validated before being passed to shell execution. Use allowlists where possible rather than escaping. Review how arguments are processed in src/args.rs and src/options.rs.
  • Low · Broad File System Watch Access — src/watch.rs and watchexec dependency. The watchexec dependency (1.17.2) provides file system watching capabilities. The application watches the entire Cargo project source for changes. If not properly restricted, this could monitor sensitive files or trigger unintended operations on symlinks or special files. Fix: Verify that file watching is restricted to project source directories and excludes sensitive locations (.git, .env files, credentials). Implement symlink attack protection and validate watch paths.
  • Low · Desktop Notification Library Usage — Cargo.toml - notify-rust dependency. The notify-rust dependency (4.7.0) sends desktop notifications. This could potentially be exploited to display misleading notifications to users if the build output or error messages are compromised. Fix: Ensure that notification content is sanitized and doesn't execute arbitrary code. Validate all content before passing to notify-rust.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · watchexec/cargo-watch — RepoPilot