Receber por email
← Voltar para o catálogo

desktop-framework-tauri

Tauri 2.x commands, IPC bridge, permission system, plugins, window management, system tray, packaging

11estrelas
Atualizado há 7 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add agents-inc/skills

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/desktop-framework-tauri/svg)](https://www.skillteca.com.br/skills/desktop-framework-tauri)

Alerta por categoria

Receba novas skills de Design e Frontend toda segunda

1 email curto, só com as skills novas de Design e Frontend. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Tauri 2.x Desktop & Mobile Apps

Quick Guide: Tauri 2.x uses system webviews (not bundled Chromium) with a Rust backend. Define Rust commands with #[tauri::command], invoke from frontend via invoke() from @tauri-apps/api/core. Every sensitive operation requires an explicit permission grant in a capability file. Plugins follow a dual-install pattern: Cargo crate + npm package. Tauri 2 supports desktop (Windows, macOS, Linux) and mobile (iOS, Android).
Current version: Tauri 2.x (stable, 2024+). Tauri 1.x is legacy and uses a fundamentally different security model (allowlist vs capabilities).

<critical_requirements>

CRITICAL: Before Using This Skill

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST use the Tauri 2.x capability/permission system -- the v1 allowlist is removed)

(You MUST register every command in tauri::generate_handler![] -- unregistered commands silently fail on invoke)

(You MUST add plugin permissions to a capability file -- plugins with missing permissions throw runtime errors)

(You MUST use #[cfg_attr(mobile, tauri::mobile_entry_point)] on pub fn run() for mobile support)

(You MUST use @tauri-apps/api/core for invoke() -- not the removed @tauri-apps/api/tauri path from v1)

</critical_requirements>

Auto-detection: Tauri, tauri.conf.json, src-tauri, tauri::command, tauri::Builder, invoke, @tauri-apps/api, tauri-plugin, capabilities, #[tauri::command], generate_handler, AppHandle, WebviewWindow, TrayIconBuilder

When to use:

  • Building desktop apps with system webview + Rust backend
  • Defining Rust commands and invoking them from frontend JavaScript/TypeScript
  • Configuring the capability/permission security model
  • Using official Tauri plugins (fs, dialog, http, notification, store, shell, etc.)
  • System tray, window management, menus
  • Packaging and distributing desktop or mobile apps
  • Migrating from Tauri v1 to v2

When NOT to use:

  • Frontend framework patterns (component architecture, state management, routing -- use respective framework skills)
  • General Rust programming not related to Tauri APIs
  • Build tool configuration (bundler, dev server -- separate tooling skill)
  • If you need full Chromium features (WebRTC, Chrome DevTools Protocol, Chrome extensions -- evaluate alternatives)

Key patterns covered:

  • Rust commands + frontend invoke bridge ([examples/core.md](examples/core.md))
  • State management via app.manage() + tauri::State<T> ([examples/core.md](examples/core.md))
  • Event system: emit/listen between frontend and backend ([examples/core.md](examples/core.md))
  • Permission/capability system ([examples/security.md](examples/security.md))
  • Official plugin installation and usage ([examples/plugins.md](examples/plugins.md))
  • Window management, system tray, menus ([examples/platform.md](examples/platform.md))
  • Packaging and distribution ([examples/packaging.md](examples/packaging.md))

Detailed resources:

  • [examples/core.md](examples/core.md) - Commands, invoke, state, events, async commands, error handling
  • [examples/security.md](examples/security.md) - Capabilities, permissions, scopes, CSP, custom permissions
  • [examples/plugins.md](examples/plugins.md) - Official plugin registry, installation pattern, common plugins
  • [examples/platform.md](examples/platform.md) - Windows, system tray, menus, multi-window, webview management
  • [examples/packaging.md](examples/packaging.md) - Build config, platform targets, updater, CI/CD
  • [reference.md](reference.md) - CLI commands, config reference, path variables, migration checklist

<philosophy>

Philosophy

Tauri is security-first, small, and native. It uses the OS system webview instead of bundling Chromium, producing binaries 10-100x smaller than alternatives. The Rust backend provides memory safety and native performance. The permission system enforces least-privilege access -- nothing is allowed unless explicitly granted.

Tauri vs alternatives -- when Tauri is the right choice:

  • You want small binary sizes (5-15 MB vs 150+ MB)
  • You want native OS integration without bundling a browser engine
  • You need a strong security model with granular permissions
  • You are comfortable with Rust for backend logic
  • You need mobile support (iOS/Android) from the same codebase

When Tauri may NOT be the right choice:

  • You need guaranteed identical rendering across platforms (Tauri uses the OS webview, which varies)
  • You need Chrome-specific APIs (WebRTC, Chrome extensions, Pepper plugins)
  • Your team has no Rust experience and cannot invest in learning it
  • You need WebView2 features not available in older Windows WebView2 versions

</philosophy>

<patterns>

Core Patterns

Pattern 1: Rust Commands + Frontend Invoke

Define commands in Rust with #[tauri::command], register them with generate_handler![], invoke from frontend. Commands support arguments, return values, async, and error handling.

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

// Register in main.rs or lib.rs
tauri::Builder::default()
    .invoke_handler(tauri::generate_handler![greet])
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
import { invoke } from "@tauri-apps/api/core";
const greeting = await invoke<string>("greet", { name: "World" });

Key point: Arguments are passed as a single object. The Rust parameter names must match the object keys. Forgetting to register a command in generate_handler![] causes silent failure. See [examples/core.md](examples/core.md) for async commands, error handling, and state access.

Pattern 2: Permission / Capability System

Every Tauri 2 app needs at least one capability file granting permissions. Without permissions, plugin and core API calls fail at runtime.

{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "main-capability",
  "description": "Capability for the main window",
  "windows": ["main"],
  "permissions": [
    "core:default",
    "shell:allow-open",
    "dialog:default",
    {
      "identifier": "fs:allow-write-text-file",
      "allow": [{ "path": "$APPDATA/*" }]
    }
  ]
}

Key point: Permissions are scoped to specific windows. Use path variables ($APPDATA, $HOME, etc.) to restrict filesystem access. The v1 allowlist is completely removed. See [examples/security.md](examples/security.md) for the full permission model.

Pattern 3: State Management

Share state between commands using app.manage() and tauri::State<T>. For mutable state, wrap in Mutex or RwLock.

use std::sync::Mutex;

struct AppState {
    counter: Mutex<i32>,
}

#[tauri::command]
fn increment(state: tauri::State<AppState>) -> i32 {
    let mut counter = state.counter.lock().unwrap();
    *counter += 1;
    *counter
}

Key point: tauri::State<T> is injected automatically when declared as a command parameter. The type must implement Send + Sync. See [examples/core.md](examples/core.md) for full patterns.

Pattern 4: Event System

Bidirectional events between frontend and backend. Frontend uses emit()/listen(), backend uses app.emit()/app.listen().

import { listen } from "@tauri-apps/api/event";

const unlisten = await listen<string>("download-progress", (event) => {
  console.log(`Progress: ${event.payload}`);
});
// Clean up when done
unlisten();
// Emit from backend to all windows
app.emit("download-progress", "50%").unwrap();

Key point: Always call the unlisten function to prevent memory leaks. Events are string-typed -- use consistent naming conventions. See [examples/core.md](examples/core.md) for targeted window events and channels.

Pattern 5: Plugin Installation Pattern

All official plugins

Compartilhar X LinkedIn