← Back to notes
Rust Ecosystem 2026-06-13 00:55 2 min read Local copy

Tauri v2 Cheatsheet — The Commands I Use on Every Project

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

Posted on Jun 13

Tauri v2 Cheatsheet — The Commands I Use on Every Project
#tauri #rust #programming #webdev

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)

Subscribe

For further actions, you may consider blocking this person and/or reporting abuse