All tests run on an 8-year-old MacBook Air. All results from shipping 7 Mac apps as a solo developer. No sponsored opinion.
After 7 Tauri apps, I type the same commands constantly. Here's the reference I wish existed when I started.
Project setup
# New project
npm create tauri-app@latest
# Add to existing project
npm install --save-dev @tauri-apps/cli
npx tauri init
Development
# Dev mode (hot reload)
npm run tauri dev
# Dev with specific log level
RUST_LOG=debug npm run tauri dev
# Dev with backend logs visible
npm run tauri dev 2>&1 | grep -v "^$"
Building
# Standard build
npm run tauri build
# Universal binary (Intel + Apple Silicon)
npm run tauri build -- --target universal-apple-darwin
# Debug build (faster, no optimization)
npm run tauri build -- --debug
Plugins
npm run tauri add global-shortcut
npm run tauri add fs
npm run tauri add shell
npm run tauri add notification
This updates both Cargo.toml and the plugin registration. Faster than doing it manually.
Permissions (tauri.conf.json)
{
"app": {
"security": {
"capabilities": [
{
"identifier": "main-capability",
"description": "Main window capabilities",
"windows": ["main"],
"permissions": [
"fs:read-all",
"fs:write-all",
"shell:execute",
"global-shortcut:allow-register"
]
}
]
}
}
}
Tauri v2 requires explicit permission declarations. If a command silently does nothing, check permissions first.
Common Rust patterns
// Get app data directory
let data_dir = app.path().app_data_dir().unwrap();
// Emit event to frontend
app_handle.emit("event-name", payload).ok();
// Get window
let window = app.get_webview_window("main").unwrap();
// App state
app.manage(MyState::new());
let state = app.state::<MyState>();
Notarization (macOS)
# Submit for notarization
xcrun notarytool submit app.dmg \
--apple-id YOUR_APPLE_ID \
--team-id YOUR_TEAM_ID \
--password YOUR_APP_PASSWORD \
--wait
# Staple after notarization
xcrun stapler staple app.dmg
Debugging
# Check what's in the bundle
unzip -l target/release/bundle/macos/App.app/Contents/MacOS/App
# Verify notarization
spctl -a -v App.app
# Check entitlements
codesign -d --entitlements - App.app
The most useful thing I learned
When a Tauri command silently fails: check the browser console first (Cmd+Option+I in dev mode), then check RUST_LOG output, then check permissions.
Silent failures in Tauri are almost always a permissions issue or a missing #[tauri::command] registration.
TL;DR: Quick Tauri v2 command reference: npm run tauri dev / tauri build -- --target universal-apple-darwin / tauri add <plugin>. Silent command failures? Check DevTools console → RUST_LOG → permissions in that order. Almost always a missing permission or unregistered command.
If this was useful, a ❤️ helps more than you'd think — thanks!
HiyokoAutoSync | X → @hiyoyok
Top comments (0)