DEV Community

Cover image for Tauri v2 Cheatsheet — The Commands I Use on Every Project
hiyoyo
hiyoyo

Posted on

Tauri v2 Cheatsheet — The Commands I Use on Every Project

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
Enter fullscreen mode Exit fullscreen mode

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 "^$"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Plugins

npm run tauri add global-shortcut
npm run tauri add fs
npm run tauri add shell
npm run tauri add notification
Enter fullscreen mode Exit fullscreen mode

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"
          ]
        }
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

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>();
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)