notify-rust
Cross-platform desktop notifications for Rust apps on Linux, macOS, and Windows.
Repository Health
Technical Analysis
notify-rust is a Rust crate for showing native desktop notifications from any Rust application. On Linux and BSD it speaks the freedesktop.org XDG notification specification over D-Bus, with a choice of the pure-Rust async zbus backend (default) or the libdbus-backed dbus-rs backend. On macOS it wraps mac-notification-sys for NSUserNotificationCenter, with an experimental UNUserNotificationCenter path behind the preview-macos-un feature, and on Windows it wraps tauri-winrt-notification for native toast notifications. A single builder-pattern Notification type exposes summaries, bodies, icons, images, urgency, hints, timeouts, action buttons, and update/close/wait-for-action handles, with per-platform support documented directly in the crate docs rather than pretending full parity.
The crate has been maintained since 2015, has 1,400+ GitHub stars, 42 contributors, and over 13 million cumulative crates.io downloads, and ships CI that builds and tests across all three target platforms plus a semver-checks workflow that guards the public API between releases.
What You Get
- A fluent
Notificationbuilder for summary, body, icon, subtitle, image, urgency, hints, timeout, and app name - Action buttons with a
wait_for_action()callback API to react to what the user clicked - Notification lifecycle control: update an existing notification in place, close it programmatically, or register an
on_closehandler - A choice of D-Bus backend on Linux/BSD — pure-Rust async
zbus(default) or libdbus-backeddbus-rs(dfeature) — switchable without changing call sites - Optional image/pixel-buffer payloads via the
imagesfeature, and file-path icons/images with no extra dependencies on any platform - Server capability and version introspection (
get_capabilities,get_server_information) on XDG targets
Common Use Cases
- Alerting a user from a long-running CLI tool or daemon when a background task finishes, fails, or needs attention
- Showing build/test/deploy status from developer tooling (watchers, CI helpers, build scripts) without a GUI framework
- Adding actionable, dismissible alerts (with buttons and close callbacks) to desktop utilities and system trays
- Cross-compiling one notification code path for a Rust app that ships on Linux, macOS, and Windows instead of writing three platform-specific integrations
Under The Hood
Architecture
The crate centers on a builder struct, Notification (src/notification.rs), with cfg-gated platform backends selected at compile time: XDG (src/xdg/mod.rs, dbus_rs.rs, zbus_rs.rs, bus.rs) implementing the freedesktop.org notification spec over D-Bus with either dbus-rs or zbus; macOS (src/macos/mod.rs, nsusernotifications.rs, unusernotifications.rs) wrapping mac-notification-sys and an experimental UNUserNotificationCenter path behind the preview-macos-un feature; and Windows (src/windows.rs) wrapping tauri-winrt-notification. Cross-cutting types — Hint (src/hints.rs + src/hints/), Urgency, Timeout, NotificationId, Error, ServerInformation, and response handling (src/response.rs) — are defined once and cfg-gated per target, so the public API surface shifts shape by platform while the Notification builder stays the single entry point every backend consumes.
Tech Stack
Rust 2021 edition, MSRV 1.89. Dependencies are almost entirely feature- and target-gated: zbus 5 (default async D-Bus) or dbus-rs 0.9 (alternate libdbus-backed backend, d feature) for Linux/BSD, mac-notification-sys 0.6 for macOS, tauri-winrt-notification 0.7 for Windows, image 0.25 plus lazy_static for optional pixel-buffer payloads, serde for D-Bus argument (de)serialization, and futures-lite for async glue. There is no web, ORM, or database layer here — it is a systems-level FFI/IPC wrapper distributed via crates.io. CI workflows (build-platforms.yml, pull-request.yml, semver-checks.yml, release.yml) build and test across Linux, macOS, and Windows and run cargo-semver-checks before release.
Code Quality
Integration-style tests live in tests/ownworld.rs and tests/realworld.rs (exercised against a D-Bus session), with conversion/unit tests in tests/conversion.rs and src/hints/tests.rs. Error handling is centralized in src/error.rs as a typed Error/ErrorKind enum with From implementations per backend (dbus::Error, zbus::Error, mac_notification_sys::Error, mac_usernotifications::Error, image errors) rather than stringly-typed errors. lib.rs sets #![deny(unsafe_code, missing_copy_implementations, trivial_casts, trivial_numeric_casts, unused_import_braces, unused_qualifications)] and #![warn(missing_docs, clippy::doc_markdown, ...)], an explicit and enforced quality bar. No property-based or fuzz testing was observed.
What Makes It Unique
Rather than committing to one D-Bus implementation, notify-rust supports both zbus (pure-Rust, async) and dbus-rs (libdbus bindings) as swappable backends behind feature flags, letting downstream users pick based on their async runtime or FFI constraints without touching call sites. Its cross-platform abstraction spans three fundamentally different notification systems — the XDG D-Bus spec, macOS NSUserNotification/UNUserNotificationCenter, and Windows WinRT toasts — behind one builder API, and documents per-method platform support directly in a compatibility table in the crate docs instead of claiming full parity. Scheduling, action-click callbacks, in-place update, and image/pixel-buffer payloads go well beyond a bare fire-and-forget notification wrapper.