Tauri framework for building cross-platform desktop applications with Rust backend and web frontend. Covers architecture, IPC commands, plugins, bundling, code signing, and security best practices. USE WHEN: user mentions "Tauri", "Rust desktop app", asks about "Tauri commands", "Tauri plugins", "Tauri IPC", "Rust + Svelte/React", "lightweight desktop app", "Tauri bundling", "Tauri security" DO NOT USE FOR: Electron applications - use `electron` skill instead

GitHub
Install command
npx skhub add claude-dev-suite/tauri
Markdown
SKILL.md

Tauri Core Knowledge

Full Reference: See advanced.md for event system, plugins (Dialog, Filesystem, Store), bundling configuration, code signing, testing patterns, and input validation.

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: tauri for comprehensive API documentation.

When NOT to Use This Skill

  • Electron applications - Use the electron skill
  • Pure Rust applications - Use Rust skill for CLI or backend-only
  • Web-only deployments - Tauri is for desktop apps
  • Mobile apps - Tauri Mobile is in alpha
  • Applications requiring Node.js ecosystem - Use Electron

Architecture

┌─────────────────────────────────────────────────────────────┐
│                      Rust Backend                            │
│  • Tauri Runtime (window management, events, plugins)       │
│  • Custom Commands (#[tauri::command])                      │
│  • State Management (tauri::State with Mutex/RwLock)        │
└──────────────────────────┬──────────────────────────────────┘
                           │ IPC (invoke / events)
┌──────────────────────────▼──────────────────────────────────┐
│                   System WebView                             │
│  • Web APIs (DOM, CSS, JavaScript) - No Node.js             │
│  • @tauri-apps/api (type-safe IPC)                          │
│  • Frontend Framework (Svelte/React/Vue)                    │
└─────────────────────────────────────────────────────────────┘

Project Structure

tauri-app/
├── src/                        # Frontend source
│   └── routes/
├── src-tauri/                  # Rust backend
│   ├── Cargo.toml
│   ├── tauri.conf.json
│   ├── capabilities/           # Permissions
│   └── src/
│       ├── main.rs
│       └── lib.rs
├── package.json
└── vite.config.ts

Configuration

tauri.conf.json

{
  "$schema": "https://schema.tauri.app/config/2",
  "productName": "My App",
  "version": "1.0.0",
  "identifier": "com.company.myapp",
  "build": {
    "beforeBuildCommand": "npm run build",
    "beforeDevCommand": "npm run dev",
    "devUrl": "http://localhost:5173",
    "frontendDist": "../build"
  },
  "app": {
    "windows": [{
      "title": "My App",
      "width": 1200,
      "height": 800,
      "center": true
    }],
    "security": {
      "csp": "default-src 'self'; script-src 'self'"
    }
  }
}

IPC Communication

Basic Command

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

pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_dialog::init())
        .invoke_handler(tauri::generate_handler![greet])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
// Frontend
import { invoke } from '@tauri-apps/api/core';

const message = await invoke<string>('greet', { name: 'World' });

Async Command with Error Handling

use serde::{Serialize, Deserialize};

#[derive(Debug, Serialize)]
pub struct CommandError {
    pub code: String,
    pub message: String,
}

#[derive(Serialize, Deserialize)]
pub struct User {
    id: u32,
    name: String,
    email: String,
}

#[tauri::command]
async fn get_user(id: u32) -> Result<User, CommandError> {
    if id == 0 {
        return Err(CommandError {
            code: "NOT_FOUND".to_string(),
            message: "User not found".to_string(),
        });
    }

    Ok(User {
        id,
        name: "Alice".to_string(),
        email: "alice@example.com".to_string(),
    })
}
interface CommandError {
  code: string;
  message: string;
}

try {
  const user = await invoke<User>('get_user', { id: 1 });
} catch (error) {
  const err = error as CommandError;
  console.error(`[${err.code}] ${err.message}`);
}

State Management

use std::sync::Mutex;
use tauri::State;

pub struct AppState {
    pub counter: Mutex<i32>,
}

#[tauri::command]
fn get_count(state: State<AppState>) -> i32 {
    *state.counter.lock().unwrap()
}

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

// In main
tauri::Builder::default()
    .manage(AppState { counter: Mutex::new(0) })
    .invoke_handler(tauri::generate_handler![get_count, increment])

Security

Capability-Based Permissions

// src-tauri/capabilities/default.json
{
  "identifier": "default",
  "windows": ["main"],
  "permissions": [
    "core:default",
    "dialog:allow-open",
    "dialog:allow-save",
    "fs:allow-read-text-file",
    "fs:allow-write-text-file",
    {
      "identifier": "fs:scope",
      "allow": ["$APPDATA/**", "$DOCUMENT/**"]
    },
    "store:default"
  ]
}

Anti-Patterns

Anti-PatternWhy It's WrongCorrect Approach
No input validation in commandsVulnerable to injectionValidate all parameters
Using .unwrap() in commandsPanics crash the appUse Result<T, E>
Exposing all filesystemSecurity riskUse scoped permissions
Synchronous blocking in commandsFreezes UIUse async functions
Not using State for shared dataData racesUse tauri::State with Mutex
Hardcoding pathsBreaks cross-platformUse BaseDirectory enum
allow-all in permissionsDefeats security modelList required permissions

Quick Troubleshooting

IssueDiagnosisSolution
"Command not found"Not registeredAdd to generate_handler![]
allowlist errors after v2V2 uses capabilitiesMigrate to capabilities/
Frontend can't read fileMissing permissionsAdd fs:allow-read-*
tauri dev shows blank windowDev server not runningCheck devUrl matches
IPC calls are slowLarge payloadMinimize data transfer
App crashes on state accessState not initializedRegister with .manage()

Quick Reference

Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

MIT

Source path

skills/desktop/tauri

Default branch

main

Latest commit

9496306

Tree SHA

fe4e2f1