How to watch for file changes

Use the `notify` crate for cross-platform file system event monitoring, as it provides a unified API that works on Linux, macOS, and Windows without requiring platform-specific code.

Use the notify crate for cross-platform file system event monitoring, as it provides a unified API that works on Linux, macOS, and Windows without requiring platform-specific code. For simple use cases, you can also rely on the watch command in your shell or inotifywait on Linux, but notify is the standard solution for Rust applications.

Here is a practical example using the notify crate to watch a specific directory for changes:

use notify::{Config, Event, RecommendedWatcher, RecursiveMode, Watcher};
use std::io;
use std::path::Path;

fn main() -> io::Result<()> {
    let path = Path::new("src"); // Directory to watch
    let mut watcher = RecommendedWatcher::new(
        |res| match res {
            Ok(event) => {
                println!("Event: {:?}", event);
                // Handle specific event types here (Create, Modify, Remove)
            }
            Err(e) => eprintln!("Watch error: {:?}", e),
        },
        Config::default(),
    )?;

    watcher.watch(path, RecursiveMode::Recursive)?;

    // Keep the program running to receive events
    loop {
        std::thread::sleep(std::time::Duration::from_secs(1));
    }
}

Add the dependency to your Cargo.toml:

[dependencies]
notify = "6.0"

If you need a quick one-off script without writing Rust code, use inotifywait on Linux:

inotifywait -m -r -e modify,create,delete /path/to/dir

On macOS or Windows, the notify crate handles the underlying differences (FSEvents, ReadDirectoryChangesW) automatically, so you don't need to write conditional compilation logic. Be aware that file watchers can be resource-intensive if monitoring large directory trees; use RecursiveMode::NonRecursive if you only need to watch a specific folder level, and ensure your event handler processes events quickly to avoid blocking the watcher thread.