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/config.toml
let database = app_path!; // → /path/to/exe/data/users.db
// Environment override for deployment
let logs = app_path!;
// → Uses LOG_PATH if set, otherwise /path/to/exe/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/
// 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
logs.create_parents?; // Creates logs/ for the file
app_path!.create_dir?; // Creates temp/ directory itself
Fallible try_app_path! Macro
use try_app_path;
let app_base = try_app_path!?; // Fallible base directory
let config = try_app_path!?;
let database = try_app_path!?;
// Error handling
match try_app_path!
Constructor API
use AppPath;
// Basic constructors
let app_base = new; // Executable directory
let config = with; // App base + path
let database = try_with?; // Fallible version
// Override constructors
let config = with_override;
let database = try_with_override?;
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_new
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.0"
Documentation
For comprehensive API documentation, examples, and guides, see docs.rs/app-path.