rfd
Rusty File Dialogs — a cross-platform Rust library for native open/save/message dialogs
Repository Health
Technical Analysis
rfd (Rusty File Dialogs) is a cross-platform Rust library that surfaces each OS’s native file-open, file-save, and message dialogs behind a single API, so a Rust application gets platform-consistent-looking dialogs on Windows, macOS, Linux/BSD, and WASM32 without hand-rolling per-platform FFI. It exposes both synchronous and asynchronous entry points, letting consumers pick blocking calls for simple CLI tools or async futures for GUI apps built on an event loop.
On Linux and BSD it supports two backends — GTK3 or the XDG Desktop Portal (with Wayland support) — selectable via Cargo feature flags, while macOS and Windows dispatch to AppKit’s NSOpenPanel/NSSavePanel and the native Win32 common dialogs respectively. This backend-per-platform architecture is what lets a single FileDialog call in application code produce a dialog that looks and behaves like every other native app on that OS.
What You Get
- A unified
FileDialogbuilder for pick-file, pick-folder, and save-file dialogs, plusMessageDialogfor native alert/confirmation dialogs - Both synchronous (blocking) and asynchronous (
Future-returning) APIs so it fits CLI tools and event-loop-driven GUI apps alike - Per-platform native backends: AppKit (macOS), Win32 common dialogs (Windows), GTK3 or XDG Desktop Portal + Wayland (Linux/BSD), and a WASM32 async-only backend
- Feature-gated backend selection (
xdg-portal,wayland,gtk3,common-controls-v6) so consumers only compile in the platform integration they need
Common Use Cases
- Adding a native ‘Open File’ or ‘Save As’ dialog to a cross-platform Rust GUI app (egui, iced, winit-based apps) without writing per-OS FFI code
- Prompting the user to pick an input/output file or directory in a Rust CLI tool that still wants a native picker experience
- Showing native confirmation/alert message boxes from a Rust desktop application
- Building a WASM-targeted Rust app (e.g. via winit + web) that still needs a browser-native file picker through the async API
Under The Hood
Architecture — rfd’s src/ splits into a platform-agnostic front end (file_dialog.rs, message_dialog.rs, oneshot.rs for the sync/async bridging) and a backend/ directory with one module per platform: macos, win_cid (Windows common dialogs), gtk3, xdg_desktop_portal (with a linux dispatcher choosing between GTK3 and the portal), and wasm. Each backend implements the same trait surface so application code calls one FileDialog API regardless of which native dialog system ends up handling the request.
Tech Stack — Rust throughout, using raw-window-handle to associate dialogs with the correct parent window across windowing systems. Platform-specific dependencies are pulled in conditionally via cfg(target_os) blocks: objc2/objc2-app-kit bindings on macOS (NSOpenPanel/NSSavePanel/NSAlert), windows-sys on Windows, and gtk-sys/wayland-client/wayland-protocols on Linux depending on the chosen feature flags.
Code Quality — The crate ships a deny.toml (cargo-deny configuration) to enforce dependency-license and advisory policy, and tracks a CHANGELOG.md across releases, both signs of deliberate maintenance discipline for a crate that has to keep pace with OS API changes across four platform backends. The examples/winit-example demonstrates real integration with a windowing library rather than only isolated unit tests, which matters more for a UI-facing crate than pure unit coverage would.
API Design — The builder-style FileDialog::new().add_filter(...).pick_file() pattern (sync) mirrors its async counterpart closely, so switching between blocking and non-blocking call sites is low-friction. Feature flags (xdg-portal, wayland, gtk3, common-controls-v6) are documented in the README with platform-specific build prerequisites, reducing the most common source of friction for cross-platform native-dialog crates: missing system dependencies at compile time on Linux.
Used by 2 apps in this directory
Cline
AI Code Assistants
An open-source AI coding agent that lives in your editor and terminal — reads and edits your codebase, runs commands, browses the web, and requires human approval for every action by default.
Jan
AI Assistants
Run LLMs 100% locally with full privacy, or connect to cloud AI — your machine, your data, your control.