cargo watch is a fantastic tool that lets you automatically rebuild your Rust project whenever you change a file. It’s like having a little automated assistant watching your code, ready to compile it the instant you save.

Let’s see it in action. Imagine you have a simple Rust project:

// src/main.rs
fn main() {
    println!("Hello, world!");
}

To start cargo watch, you’ll first need to install it:

cargo install cargo-watch

Then, in your project directory, simply run:

cargo watch -x run

Now, if you open src/main.rs and change the message to "Hello, Rustaceans!" and save the file, cargo watch will automatically detect the change and run your program again, outputting:

Hello, Rustaceans!

This is incredibly useful for rapid development, especially when you’re working on smaller changes and want to see the results immediately without the manual step of typing cargo run every single time.

How it Works Under the Hood

At its core, cargo watch works by monitoring your project’s files for changes. When it detects a modification, it triggers a specified command. The most common command is, of course, cargo run to execute your application, but you can also use it to run tests (-x test), build your project (-x build), or even execute arbitrary shell commands.

The primary configuration for cargo watch involves specifying the command to run and what files to watch. By default, it watches all files within your project directory that cargo would normally consider. You can customize this behavior. For example, to only watch .rs files and run cargo test:

cargo watch --filter '\.rs$' -x test

Here, --filter '\.rs$' tells cargo watch to only pay attention to files ending with .rs. The $ anchors the match to the end of the filename, ensuring it only matches Rust source files.

You can also specify multiple commands to run sequentially or in parallel. If you want to build and then run your project:

cargo watch -x build -x run

This will first execute cargo build and, if successful, then execute cargo run.

Beyond the Basics: Customization and Control

cargo watch offers several options for fine-tuning its behavior. One of the most powerful is the ability to ignore certain files or directories. This is particularly useful if you have generated files or temporary directories that you don’t want to trigger recompilation.

For instance, if you have a tmp/ directory where intermediate build artifacts are placed, you can ignore it like this:

cargo watch --ignore 'tmp/' -x run

The --ignore flag takes a regular expression that matches against the path of the changed file.

Another common scenario is dealing with larger projects where a full rebuild might take a while. cargo watch has a --delay option that allows you to set a debounce interval. This means that after a file change, cargo watch will wait for a specified duration (in milliseconds) before triggering the command. If another file change occurs within that delay, the timer resets. This prevents your build from running multiple times in quick succession if you’re making rapid, small edits.

cargo watch --delay 500 -x run

This command will wait for 500 milliseconds after the last file change before running cargo run.

For more complex workflows, you can even define custom commands. Let’s say you want to run a linter before building. You can define a custom command and then tell cargo watch to execute it. While cargo watch doesn’t have a direct alias feature for complex command chains within its CLI, you can achieve this by using shell scripting or by creating a dedicated script file that cargo watch executes.

A simpler approach for running multiple commands is to use && within a single -x argument, though this is less flexible than separate -x calls for independent execution:

cargo watch -x "cargo clippy && cargo run"

This will run cargo clippy and, if it succeeds, then run cargo run.

The --poll option is also worth noting. By default, cargo watch uses OS-level file system event notifications. However, on some systems or in certain environments (like some network file systems), these events might be unreliable. In such cases, --poll forces cargo watch to periodically check file modification times, which is less efficient but more robust:

cargo watch --poll -x run

The real power of cargo watch comes from its ability to integrate seamlessly into your daily coding loop. It removes friction, allowing you to focus on writing code and seeing its effects almost instantaneously. It’s not just about convenience; it’s about accelerating the feedback cycle that is so crucial for productive software development.

The next logical step after getting comfortable with auto-rebuilding is to explore how cargo watch can integrate with debugging workflows, perhaps by automatically launching your debugger on a failed build or test.

Want structured learning?

Take the full Cargo course →