惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
J
Java Code Geeks
B
Blog
腾讯CDC
博客园 - 三生石上(FineUI控件)
S
SegmentFault 最新的问题
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - Franky
罗磊的独立博客
月光博客
月光博客
Jina AI
Jina AI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
D
Docker
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
G
Google Developers Blog
V
Visual Studio Blog
I
InfoQ
有赞技术团队
有赞技术团队
D
DataBreaches.Net
Microsoft Security Blog
Microsoft Security Blog
WordPress大学
WordPress大学
阮一峰的网络日志
阮一峰的网络日志
宝玉的分享
宝玉的分享
Blog — PlanetScale
Blog — PlanetScale

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Tauri v2 Cheatsheet — Commands, Events, Permissions, and ...
hiyoyo · 2026-05-04 · via DEV Community
Cover image for Tauri v2 Cheatsheet — Commands, Events, Permissions, and State in One Place

hiyoyo

If this is useful, a ❤️ helps others find it.

Everything I keep looking up when building Tauri v2 apps — in one place.


Tauri Commands (Rust → Frontend)

// Define
#[tauri::command]
fn greet(name: String) -> String {
    format!("Hello, {}!", name)
}

// With error handling
#[tauri::command]
fn read_file(path: String) -> Result {
    std::fs::read_to_string(path).map_err(|e| e.to_string())
}

// Async
#[tauri::command]
async fn fetch_data(url: String) -> Result {
    // async work here
    Ok("data".to_string())
}

// Register
tauri::Builder::default()
    .invoke_handler(tauri::generate_handler![greet, read_file, fetch_data])

Enter fullscreen mode Exit fullscreen mode

// Call from frontend
import { invoke } from '@tauri-apps/api/core';

const result = await invoke('greet', { name: 'world' });
const data = await invoke('fetch_data', { url: 'https://...' });

Enter fullscreen mode Exit fullscreen mode


Events (Rust ↔ Frontend)

// Rust → Frontend
window.emit("my-event", serde_json::json!({"key": "value"})).unwrap();

// App-wide
app.emit("global-event", payload).unwrap();

Enter fullscreen mode Exit fullscreen mode

// Frontend → listen
import { listen } from '@tauri-apps/api/event';

const unlisten = await listen('my-event', (event) => {
  console.log(event.payload);
});

// Cleanup
unlisten();

// Frontend → Rust (via command, not events)
await invoke('handle_action', { data: 'value' });

Enter fullscreen mode Exit fullscreen mode


State Management

// Define state
pub struct AppState {
    pub counter: Mutex,
}

// Register
tauri::Builder::default()
    .manage(AppState { counter: Mutex::new(0) })

// Use in command
#[tauri::command]
fn increment(state: tauri::State) -> u32 {
    let mut counter = state.counter.lock().unwrap();
    *counter += 1;
    *counter
}

Enter fullscreen mode Exit fullscreen mode


Permissions (v2 — capabilities/)

// src-tauri/capabilities/main.json
{
  "identifier": "main-capability",
  "windows": ["main"],
  "permissions": [
    "core:default",
    "shell:allow-execute",
    "shell:allow-stdin",
    "fs:allow-read-files",
    "fs:allow-write-files",
    "fs:allow-app-cache-write",
    "dialog:allow-open",
    "dialog:allow-save",
    "notification:default"
  ]
}

Enter fullscreen mode Exit fullscreen mode


Window Config

// tauri.conf.json
{
  "app": {
    "windows": [{
      "label": "main",
      "title": "My App",
      "width": 800,
      "height": 600,
      "resizable": true,
      "decorations": true,
      "transparent": false,
      "alwaysOnTop": false,
      "fullscreen": false,
      "visible": true
    }],
    "macOS": {
      "activationPolicy": "regular"
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

For menubar app: "activationPolicy": "accessory"


System Tray

use tauri::tray::{TrayIconBuilder, TrayIconEvent};

TrayIconBuilder::new()
    .icon(app.default_window_icon().unwrap().clone())
    .on_tray_icon_event(|tray, event| {
        if let TrayIconEvent::Click { .. } = event {
            let app = tray.app_handle();
            if let Some(window) = app.get_webview_window("main") {
                window.show().unwrap();
                window.set_focus().unwrap();
            }
        }
    })
    .build(app)?;

Enter fullscreen mode Exit fullscreen mode


Common Plugin Setup

# Cargo.toml
[dependencies]
tauri-plugin-store = "2"
tauri-plugin-global-shortcut = "2"
tauri-plugin-notification = "2"
tauri-plugin-dialog = "2"
tauri-plugin-fs = "2"
tauri-plugin-shell = "2"

Enter fullscreen mode Exit fullscreen mode

tauri::Builder::default()
    .plugin(tauri_plugin_store::Builder::new().build())
    .plugin(tauri_plugin_global_shortcut::Builder::new().build())
    .plugin(tauri_plugin_notification::init())
    .plugin(tauri_plugin_dialog::init())
    .plugin(tauri_plugin_fs::init())
    .plugin(tauri_plugin_shell::init())

Enter fullscreen mode Exit fullscreen mode


Build Commands

# Dev
cargo tauri dev

# Build for current arch
cargo tauri build

# Universal binary (Intel + Apple Silicon)
cargo tauri build --target universal-apple-darwin

# iOS (Tauri v2)
cargo tauri ios build

# Android (Tauri v2)
cargo tauri android build

Enter fullscreen mode Exit fullscreen mode


Hiyoko PDF Vault → https://hiyokoko.gumroad.com/l/HiyokoPDFVault
X → @hiyoyok