How Rustlings Watches Files for Changes: A Deep Dive into the Watch Mode Implementation

Yes, Rustlings supports automatic file watching through a built-in watch mode that monitors the exercises/ directory and re-runs the current exercise whenever you save changes.

The rust-lang/rustlings repository includes a sophisticated file watching system that eliminates the need to manually restart the tool after every edit. This feature leverages the notify crate to provide cross-platform file system monitoring, creating a tight feedback loop that makes learning Rust more interactive.

How Rustlings Implements File Watching

The watch mode architecture separates concerns across multiple modules, with the core detection logic residing in src/watch.rs and state management handled in src/watch/state.rs.

The Core Watcher Setup in src/watch.rs

When you start Rustlings without the --manual-run flag, the watch() function initializes a RecommendedWatcher from the notify crate. This watcher is configured to recursively monitor the exercises/ directory, polling every second for changes.

// src/watch.rs (excerpt)
let _watcher_guard = if let Some(exercise_names) = notify_exercise_names {
    let notify_event_handler = NotifyEventHandler::build(watch_event_sender.clone(), exercise_names)?;
    let mut watcher = RecommendedWatcher::new(
        notify_event_handler,
        Config::default()
            .with_follow_symlinks(false)
            .with_poll_interval(Duration::from_secs(1)),
    )?;
    watcher.watch(Path::new("exercises"), RecursiveMode::Recursive)?;
    Some(watcher)
} else {
    manual_run = true;
    None
};

The NotifyEventHandler (defined in src/watch/notify_event.rs) translates raw file system events into internal WatchEvent::FileChange messages, which are sent through a channel to the main watch loop.

Handling File Change Events

When a file change is detected, run_watch() matches on WatchEvent::FileChange and delegates to WatchState::handle_file_change() in src/watch/state.rs. This method verifies whether the changed file belongs to the current exercise before re-executing:

// src/watch/state.rs (excerpt)
pub fn handle_file_change(&mut self, exercise_ind: usize, stdout: &mut StdoutLock) -> Result<()> {
    if self.app_state.current_exercise_ind() != exercise_ind {
        return Ok(());
    }
    self.run_current_exercise(stdout)
}

This selective re-execution prevents unnecessary runs when you modify files unrelated to the active exercise, optimizing performance while maintaining responsiveness.

Using Rustlings Watch Mode

The watch mode operates transparently during normal usage, but you can control its behavior through CLI flags when necessary.

Starting Watch Mode

By default, Rustlings automatically enables file watching when you run:

rustlings

Once active, the tool displays the current exercise and waits for events. When you save changes to any file within exercises/, the UI updates automatically:

Checking the exercise `variables2`. Please wait…
... (output of the check)
Exercise done ✓
Hint
...
n:next / r:run / h:hint / l:list / c:check all / x:reset / q:quit ?

If you modify exercises/variables2/src/main.rs while the prompt is waiting, the program detects the change and re-runs the exercise without requiring additional input.

Manual Run Mode

If the file watcher cannot initialize (for example, on Windows systems without proper support) or if you prefer explicit control, Rustlings provides a fallback manual run mode. You can explicitly disable watching with:

rustlings --manual-run

In this mode, the tool executes the current exercise once and returns to the prompt, waiting for you to press r to re-run rather than monitoring files automatically. The constant NOTIFY_ERR in src/watch.rs defines the error message displayed when the watcher fails to initialize, guiding users toward this flag.

Key Files in the Watch System

The file watching functionality spans several modules in the Rustlings codebase:

  • src/watch.rs — Initializes the RecommendedWatcher, configures the notify event handler, and coordinates the main watch/list loops.
  • src/watch/state.rs — Maintains watch-mode state, renders the terminal UI, and handles FileChange events by re-running exercises.
  • src/watch/notify_event.rs — Implements the notify::EventHandler trait to convert raw file-system events into internal WatchEvent messages.
  • src/watch/terminal_event.rs — Listens for keyboard input during watch mode, handling commands like n (next), r (run), and q (quit).
  • src/main.rs — Entry point that parses CLI arguments (including --manual-run) and decides whether to invoke watch mode.

Summary

  • Rustlings includes native file watching that monitors the exercises/ directory for changes using the notify crate.
  • The watcher runs automatically when you start rustlings without the --manual-run flag, re-executing the current exercise upon file saves.
  • Implementation spans src/watch.rs and src/watch/state.rs, utilizing RecommendedWatcher with a 1-second poll interval and recursive directory monitoring.
  • Manual run mode provides a fallback when file system watching is unavailable or undesirable, requiring explicit r keypresses to re-run exercises.

Frequently Asked Questions

How do I disable file watching in Rustlings?

Use the --manual-run flag when starting the tool: rustlings --manual-run. This disables the automatic file watcher and requires you to press r to manually re-run exercises after making changes.

What happens if Rustlings cannot initialize the file watcher?

If the RecommendedWatcher fails to initialize (which can occur on certain Windows configurations or restricted environments), Rustlings automatically falls back to manual run mode. The tool displays the NOTIFY_ERR message defined in src/watch.rs and operates as if --manual-run had been specified.

Which directory does Rustlings watch for changes?

Rustlings recursively monitors the exercises/ directory relative to the project root. The watcher is configured in src/watch.rs with RecursiveMode::Recursive, meaning it detects changes in any subdirectory or file within the exercises folder, including src/main.rs files for individual exercises.

Can I use Rustlings watch mode in CI environments?

While possible, it is not recommended. File watching requires a persistent process and active file system event monitoring, which may not function reliably in containerized or headless CI environments. For continuous integration, use rustlings --manual-run or run specific exercise verification commands that exit after completion rather than waiting for file changes.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →