Native Integration
Filesystem access, notifications, and OS APIs from Rust desktop apps - portable patterns and platform caveats.
Search across all documentation pages
Filesystem access, notifications, and OS APIs from Rust desktop apps - portable patterns and platform caveats.
fn app_data_dir() -> std::io::Result<std::path::PathBuf> {
let base = dirs::data_local_dir().ok_or(std::io::ErrorKind::NotFound)?;
Ok(base.join("com.example.myapp"))
}When to reach for this:
fn ensure_data_dir() -> std::io::Result<std::path::PathBuf> {
let dir = app_data_dir()?;
std::fs::create_dir_all(&dir)?;
Ok(dir)
}
fn app_data_dir() -> std::io::Result<std::path::PathBuf> {
let base = dirs::data_local_dir().ok_or(std::io::ErrorKind::NotFound)?;
Ok(base.join("com.example.myapp"))
}
fn pick_config_file() -> Option<std::path::PathBuf> {
rfd::FileDialog::new()
.add_filter("toml", &["toml"])
.pick_file()
}What this demonstrates:
dirs| Need | Crate / API |
|---|---|
| App data path | dirs, Tauri paths |
| File dialog | rfd, Tauri dialog plugin |
| Notifications | tauri-plugin-notification |
| Secrets | keyring |
/Users/... paths - breaks Linux/Windows. Fix: always dirs or Tauri resolver.| Alternative | Use When | Don't Use When |
|---|---|---|
| CLI only | Server tools | Desktop UX required |
Electron @electron/remote | Legacy app | Tauri/Rust security model |
| Platform-specific FFI | Missing abstraction | Portable app priority |
| Web app only | No native APIs | Need filesystem offline |
Declare allowed directories in capabilities; use app_data_dir for default writable root.
Tauri webview events or winit drop handlers in raw egui/iced - validate paths before read.
Open URLs and folders with open crate or Tauri shell plugin - never pass unsanitized user strings to shell.
tauri-plugin-single-instance or file lock on startup for Windows tray apps.
dark-light crate or Tauri theme events to sync UI with OS setting.
Platform-specific crates or installer scripts - document privacy impact to users.
Flatpak/snap use XDG portals for file access - test packaged builds not only cargo run.
Writing to Program Files fails - use %LOCALAPPDATA% via dirs.
Inject trait FileSystem mock; integration tests use tempfile directories.
Installers register MIME handlers - see Packaging & Distribution.
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.
Reviewed by Chris St. John·Last updated Jul 19, 2026