Skip to content
Development
Skill

/desktop-backend-tauri

Tauri 2.x Rust command patterns, state management, error handling, events, channels, testing

From plugin
skills
26200 skills

Claude Code

$ npx -y skills add agents-inc/skills --skill desktop-backend-tauri --agent claude-code

SKILL.md

desktop-backend-tauri.SKILL.md
name: desktop-backend-tauri
description: Tauri 2.x Rust command patterns, state management, error handling, events, channels, testing

Tauri Rust Backend Patterns

> **Quick Guide:** Define commands with `#[tauri::command]`, register in `generate_handler![]`. Use `State<T>` for shared state (wrap mutable fields in `Mutex`). Error types must implement both `serde::Serialize` and `Display` -- use `thiserror` for ergonomic error enums. Async commands run on Tokio -- borrowed args (`&str`, `State<'_, T>`) require `Result<T, E>` return type. Stream data to frontend via `Channel<T>` (not events) for high throughput. Emit events with `app.emit()` for fire-and-forget notifications. > > **Current version:** Tauri 2.x (stable). Async runtime is Tokio.

---

<critical_requirements>

CRITICAL: Before Using This Skill

**(You MUST register every command in `tauri::generate_handler![]` -- unregistered commands compile fine but silently fail at runtime)**

**(You MUST implement `serde::Serialize` on all error types returned from commands -- Tauri serializes errors across the IPC boundary)**

**(You MUST wrap mutable managed state in `Mutex` or `RwLock` -- commands run concurrently and `State<T>` requires `Send + Sync`)**

**(You MUST return `Result<T, E>` from async commands that use borrowed args (`&str`, `State<'_, T>`) -- Rust lifetime rules require it)**

**(You MUST use `Channel<T>` for streaming data to frontend -- events are designed for small payloads, not high-throughput streaming)**

</critical_requirements>

---

**Auto-detection:** #[tauri::command], tauri::command, tauri::State, AppHandle, app.manage, generate_handler, tauri::ipc::Channel, Emitter, Listener, thiserror, tauri::test, mock_builder, async tauri command, tauri error handling, tauri state management

**When to use:**

  • Defining Rust command handlers (sync and async) for frontend invocation
  • Managing application state across commands with `app.manage()` and `State<T>`
  • Implementing error types that serialize across the IPC boundary
  • Emitting events from Rust to frontend (progress, notifications, background updates)
  • Streaming data from Rust to frontend via channels
  • Testing Rust commands with Tauri's mock runtime
  • Organizing commands into modules as the backend grows

**When NOT to use:**

  • Frontend invoke patterns and TypeScript types (see the framework-level Tauri skill)
  • Permission/capability configuration (see the framework-level Tauri skill)
  • Plugin installation and configuration (see the framework-level Tauri skill)
  • Window management, system tray, menus (see the framework-level Tauri skill)
  • Packaging and distribution (see the framework-level Tauri skill)
  • General Rust programming not specific to Tauri APIs

**Key patterns covered:**

  • Sync and async commands with `#[tauri::command]` ([examples/core.md](examples/core.md))
  • Error handling with `thiserror` + manual `Serialize` impl ([examples/core.md](examples/core.md))
  • Managed state with `Mutex`/`RwLock` and `State<T>` injection ([examples/core.md](examples/core.md))
  • `AppHandle` for accessing app resources from commands ([examples/core.md](examples/core.md))
  • Channels for streaming data to frontend ([examples/core.md](examples/core.md))
  • Emitting events from Rust ([examples/events.md](examples/events.md))
  • Listening for frontend events in Rust ([examples/events.md](examples/events.md))
  • Testing commands with mock runtime ([examples/testing.md](examples/testing.md))
  • Command organization in modules ([examples/core.md](examples/core.md))

**Detailed resources:**

  • [examples/core.md](examples/core.md) - Commands, error handling, state, AppHandle, channels, modules
  • [examples/events.md](examples/events.md) - Emitting and listening for events from Rust
  • [examples/testing.md](examples/testing.md) - Mock runtime, testing commands with state
  • [reference.md](reference.md) - Decision frameworks, quick-lookup tables, lifetime rules

---

<philosophy>

Philosophy

The Tauri Rust backend is the **trust boundary** between the untrusted webview frontend and the operating system. Every sensitive operation -- file I/O, network requests, shell commands, state mutations -- flows through Rust commands. The backend is responsible for validation, authorization, and safe execution.

**Design principles:**

  • **Commands are the API surface.** Each command is a well-defined endpoint with typed arguments, typed return values, and explicit error handling. Treat them like HTTP handlers.
  • **State is managed, not global.** Use `app.manage(T)` to register singletons. Commands request state via `State<T>` injection -- no global statics, no lazy_static.
  • **Errors are data, not panics.** Never `unwrap()` in commands. Return `Result<T, E>` where `E` implements `Serialize`. The frontend receives structured error information.
  • **Async by default for I/O.** Sync commands block the main thread. Use async for anything involving files, network, or long computation. Tokio is the runtime.
  • **Channels for streaming, events for notifications.** `Channel<T>` is optimized for ordered, high-throughput data delivery. Events are pub-sub fire-and-forget for small payloads.

</philosophy>

---

<patterns>

Core Patterns

Pattern 1: Sync and Async Commands

Sync commands execute on the main thread. Async commands run on Tokio's thread pool.

// Sync -- blocks main thread, use only for fast operations
#[tauri::command]
fn greet(name: &str) -> String {
    format!("Hello, {}!", name)
}

// Async -- runs on Tokio, use for I/O and long operations
#[tauri::command]
async fn read_file(path: String) -> Result<String, String> {
    tokio::fs::read_to_string(&path)
        .await
        .map_err(|e| e.to_string())
}

**Key rule:** Async commands cannot use `&str` arguments unless the return type is `Result<T, E>`. Use `String` for owned args, or wrap in `Result` to satisfy Rust's async lifetime constraints.

See [examples/core.md](examples/core.md) for command registr

Read more
@agents-inc
Ships withskills

The official skills marketplace for Agents Inc. 230+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?

Stars on GitHub

Momentum

stars in total
26
Star history of agents-inc/skills on GitHub, a chart by star-history.com

Other skills on skills.

ai-infrastructure-litellm

ai-infrastructure-lite…

LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking,…

@agents-inc@agents-incInstall Skill
ai-infrastructure-modal

ai-infrastructure-moda…

Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client…

@agents-inc@agents-incInstall Skill
ai-infrastructure-ollama

ai-infrastructure-olla…

Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output,…

@agents-inc@agents-incInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about desktop-backend-tauri.

Which coding agents can use desktop-backend-tauri?
desktop-backend-tauri installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.