app-path
Create portable applications that keep files together with the executable.
Simple, zero-dependency library for creating portable applications where configuration, data, and executable stay together as a deployable unit.
use app_path;
// Files relative to your executable - not current directory!
let config = app_path!; // → /path/to/exe_dir/config.toml
let database = app_path!; // → /path/to/exe_dir/data/users.db
// Environment override for deployment
let logs = app_path!;
// → Uses LOG_PATH if set, otherwise /path/to/exe_dir/logs/app.log
// Acts like std::path::Path + creates directories
if !config.exists
Why Choose AppPath?
| Approach | Problem | AppPath Solution |
|---|---|---|
| Hardcoded paths | Breaks when moved | ✅ Works anywhere |
current_dir() |
Depends on where user runs program | ✅ Always relative to executable |
| System directories | Scatters files across system | ✅ Self-contained, portable |
current_exe() |
Manual path joining, no caching, verbose error handling | ✅ Clean API, automatic caching, ergonomic macros |
Features
- 🚀 Zero dependencies - Only standard library
- ✨ Ergonomic macro - Clean syntax with
app_path! - 🌍 Cross-platform - Windows, Linux, macOS
- ⚡ High performance - Static caching, minimal allocations
- 🔧 Flexible deployment - Environment overrides
- 🛡️ Thread-safe - Concurrent access safe
- 📦 Portable - Entire app moves as one unit
API Overview
The app_path! Macro (Recommended)
use app_path;
// Application base directory
let app_base = app_path!; // → /path/to/exe_dir/
// Simple paths
let config = app_path!;
let database = app_path!;
// Environment overrides
let logs = app_path!;
let cache = app_path!;
// Custom override logic
let data_dir = app_path!;
// Function-based override (great for XDG support)
let config_dir = app_path!;
// Variable capturing
let version = "1.0";
let versioned_cache = app_path!;
// Directory creation
app_path!.create_parents?; // Creates `logs/` for the `app.log` file
app_path!.create_dir?; // Creates `temp/` directory itself
Note: Use
try_app_path!instead ofapp_path!when you needResultreturn values for explicit error handling (same syntax, just returnsResult<AppPath, AppPathError>instead of panicking).
Constructor API
use AppPath;
// Basic constructors
let app_base = new; // Executable directory
let config = with; // App base + path
// Override constructors
let config = with_override;
// Function-based override constructors
let logs = with_override_fn;
Note: All constructors have
try_*variants that returnResultinstead of panicking (e.g.,try_new(),try_with(),try_with_override(),try_with_override_fn()).
Real-World Examples
Configuration Management
use app_path;
CLI Tool with File Management
use app_path;
Deployment Flexibility
use app_path;
// Same binary, different environments:
// Development: uses "./config/app.toml"
// Production: CONFIG_PATH="/etc/myapp/config.toml" overrides to absolute path
let config = app_path!;
// Conditional deployment paths
let logs = if cfg! else ;
Error Handling
AppPath uses fail-fast by default for better developer experience:
app_path!andAppPath::new()- Panic on critical system errors (executable location undetermined)try_app_path!andAppPath::try_new()- ReturnResultfor explicit error handling
This design makes sense because if the system can't determine your executable location, there's usually no point continuing - it indicates severe system corruption or unsupported platforms.
For most applications: Use the panicking variants (app_path!) - they fail fast on unrecoverable errors.
For libraries: Use the fallible variants (try_app_path!) to let callers handle errors gracefully.
use ;
// Libraries should handle errors explicitly
match try_with
Ecosystem Integration
app-path integrates seamlessly with popular Rust path crates, letting you combine the best tools for your specific needs:
🔗 Popular Path Crate Compatibility
| Crate | Use Case | Integration Pattern |
|---|---|---|
camino |
UTF-8 path guarantees for web apps | Utf8PathBuf::from_path_buf(app_path.into())? |
typed-path |
Cross-platform type-safe paths | WindowsPath::new(app_path.to_bytes()) |
📝 Real-World Integration Examples
🌐 JSON-Safe Web Config (with camino)
use app_path;
use Utf8PathBuf;
let static_dir = app_path!;
let utf8_static = from_path_buf
.map_err?;
let config = json!;
🔨 Cross-Platform Build System (with typed-path)
use app_path;
use ;
let dist_dir = app_path!;
let path_bytes = dist_dir.to_bytes;
let win_path = new; // Uses \ on Windows
let unix_path = new; // Uses / on Unix
⚙️ Configuration Files (with serde)
use AppPath;
use ;
// Convert when using - clean separation of concerns
let config: Config = from_str?;
let log_path = with;
let data_path = with;
Installation
[]
= "1.1"
Documentation
For comprehensive API documentation, examples, and guides, see docs.rs/app-path.