Skip to content
🔭 Cross-platform filesystem notification library for Rust.
Branch: main
Clone or download
passcod [docs] Push minimum rustc to 1.32.0
The ecosystem is moving to edition 2018 wholesale and bringing a lot of
breaking changes via dependency versioning for crates that aren't
compatible. I don't like adding yet one more change to this release, but
the plan is NOT to bring the code to 2018 standard, instead to push the
CI and guarantees and leave everything as is for the first release.
Later point releases will be able to refactor for new features and into
the new edition.
Latest commit 56aac12 May 28, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github [docs] Add github issue/PR templates Apr 20, 2019
examples [api] Rename new_raw to new_immediate Mar 30, 2019
src [libs] Update fsevent to 0.4 (#195) May 22, 2019
tests [ci] Auto-retry only failed tests up to three times May 8, 2019
.editorconfig [docs] Bring module docs in line with new readme Mar 30, 2019
.gitignore [ci] Auto-retry only failed tests up to three times May 8, 2019
.travis.yml [docs] Push minimum rustc to 1.32.0 May 28, 2019 [docs] Push minimum rustc to 1.32.0 May 28, 2019
Cargo.toml [docs] Push minimum rustc to 1.32.0 May 28, 2019
LICENSE [docs] Add github issue/PR templates Apr 20, 2019
LICENSE.ARTISTIC [meta] Simplify dual-licensing header Apr 18, 2019
clippy.toml Refer to macOS by that name rather than OS X. Apr 7, 2018


» Crate » Docs » CI » Downloads » Conduct » Public Domain

Cross-platform filesystem notification library for Rust.

This is the readme for the upcoming 5.0 release! Look at the 4.0 one instead.

(Looking for desktop notifications instead? Have a look at notify-rust or alert-after!)

As used by: alacritty, cargo watch, cobalt, docket, handlebars-iron, mdBook, pax, rdiff, rust-analyzer, timetrack, watchexec, xi-editor, and others. (Want to be added to this list? Open a pull request!)


notify = "5.0.0"


use notify::{RecommendedWatcher, RecursiveMode, Result, watcher};
use std::time::Duration;

fn main() -> Result<()> {
    // Automatically select the best implementation for your platform.
    // You can also access each implementation directly e.g. INotifyWatcher.
    let mut watcher = watcher(Duration::from_secs(2))?;

    // Add a path to be watched. All files and directories at that path and
    // below will be monitored for changes."/home/test/notify", RecursiveMode::Recursive)?;

    // This is a simple loop, but you may want to use more complex logic here,
    // for example to handle I/O.
    for event in &watcher {
        match event {
            Ok(event) => println!("changed: {:?}", event.path),
            Err(err) => println!("watch error: {:?}", err),


With a channel

To get a channel for advanced or flexible cases, use:

let rx =;

loop {
    match rx.recv() {
        // ...

To pass in a channel manually:

let (tx, rx) = crossbeam_channel::unbounded();
let mut watcher: RecommendedWatcher = Watcher::with_channel(tx, Duration::from_secs(2))?;

for event in rx.iter() {
    // ...

With precise events

By default, Notify issues generic events that carry little additional information beyond what path was affected. On some platforms, more is available; stay aware though that how exactly that manifests varies. To enable precise events, use:

use notify::Config;

With notice events

Sometimes you want to respond to some events straight away, but not give up the advantages of debouncing. Notice events appear once immediately when the occur during a debouncing period, and then a second time as usual at the end of the debouncing period:

use notify::Config;

With ongoing events

Sometimes frequent writes may be missed or not noticed often enough. Ongoing write events can be enabled to emit more events even while debouncing:

use notify::Config;

Without debouncing

To receive events as they are emitted, without debouncing at all:

let mut watcher = immediate_watcher()?;

With a channel:

let (tx, rx) = unbounded();
let mut watcher: RecommendedWatcher = Watcher::immediate_with_channel(tx)?;


Events can be serialisable via serde. To enable the feature:

notify = { version = "5.0.0", features = ["serde"] }


  • Linux / Android: inotify
  • macOS: FSEvents
  • Windows: ReadDirectoryChangesW
  • All platforms: polling


Due to the inner security model of FSEvents (see FileSystemEventSecurity), some event cannot be observed easily when trying to follow files that do not belong to you. In this case, reverting to the pollwatcher can fix the issue, with a slight performance cost.

Next generation

While this current version continues to be developed and maintained, a next generation design of the library lives in the next branch. There is no solid ETA, beyond that most of it will not be released before async/await is stabilised in Rust. For an overview and background, see this draft announce.

Instead of one large release, though, it is much more likely that smaller components of the design, once they have gone through revising and maturing in the next branch, will be incorporated in the main branch. The first large piece, a new event classification system, landed in 5.0.

Do be aware of the licensing difference. Notify is so far under CC0. The next branch is instead under the Artistic License 2.0. Pieces of the next branch brought to main are dual-licensed under CC0, but the eventual plan is to be entirely Artistic License 2.0 code. The formal license change will incur a major version bump.


Inspired by Go's fsnotify and Node.js's Chokidar, born out of need for cargo watch, and general frustration at the non-existence of C/Rust cross-platform notify libraries.

Written by Félix Saparelli and awesome contributors.

You can’t perform that action at this time.