# Tauri Syntax State

> >

- **Type:** Skill
- **Install:** `agentstack add skill-impertio-studio-tauri-2-claude-skill-package-tauri-syntax-state`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [Impertio-Studio](https://agentstack.voostack.com/s/impertio-studio)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [Impertio-Studio](https://github.com/Impertio-Studio)
- **Source:** https://github.com/Impertio-Studio/Tauri-2-Claude-Skill-Package/tree/main/skills/source/tauri-syntax/tauri-syntax-state
- **Website:** https://github.com/OpenAEC-Foundation

## Install

```sh
agentstack add skill-impertio-studio-tauri-2-claude-skill-package-tauri-syntax-state
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# tauri-syntax-state

## Quick Reference

### State Registration (Tauri 2.x)

| Method | Context | Description |
|--------|---------|-------------|
| `Builder::manage(T)` | Builder chain | Register state during app construction |
| `App::manage(T)` | `setup()` hook | Register state that depends on app initialization |
| `AppHandle::manage(T)` | Any context | Register state at runtime (rare) |

### State Access

| Method | Context | Returns |
|--------|---------|---------|
| `State` | Command parameter | Injected automatically by Tauri |
| `app_handle.state::()` | Any code with AppHandle | `State` (panics if not registered) |
| `app_handle.try_state::()` | Any code with AppHandle | `Option>` (safe) |

### Thread-Safety Wrappers

| Wrapper | Use Case | Lock Method |
|---------|----------|-------------|
| `std::sync::Mutex` | Mutable state, no `.await` while locked | `.lock().unwrap()` |
| `tokio::sync::Mutex` | Mutable state with `.await` while locked | `.lock().await` |
| `std::sync::RwLock` | Read-heavy access, concurrent readers | `.read().unwrap()` / `.write().unwrap()` |
| None (immutable) | Read-only config data | Direct field access |

---

## Critical Warnings

**NEVER** use `State` when you registered `Mutex` — the type must match EXACTLY or Tauri panics at runtime, not at compile time. If you registered `Mutex`, the command parameter must be `State>`.

**NEVER** wrap managed state in `Arc` — Tauri already wraps all managed state in `Arc` internally. Using `app.manage(Arc::new(data))` adds a redundant layer.

**NEVER** lock the same `Mutex` twice in the same call chain — this causes a deadlock. If a function holding a lock calls another function that also locks, the thread blocks forever.

**NEVER** use `tokio::sync::Mutex` unless you need to hold the lock across `.await` points — `std::sync::Mutex` is more efficient for synchronous access.

**ALWAYS** register state before any command tries to access it — accessing unregistered state via `State` causes a runtime panic.

**ALWAYS** match the exact registered type in `State` — including all wrappers like `Mutex`, `RwLock`, etc.

---

## Essential Patterns

### Pattern 1: Immutable State (Read-Only Config)

```rust
// Tauri 2.x — No Mutex needed for read-only data
struct AppConfig {
    api_url: String,
    max_retries: u32,
}

tauri::Builder::default()
    .manage(AppConfig {
        api_url: "https://api.example.com".into(),
        max_retries: 3,
    })
    .invoke_handler(tauri::generate_handler![get_api_url])

#[tauri::command]
fn get_api_url(config: tauri::State) -> String {
    config.api_url.clone()
}
```

### Pattern 2: Mutable State with std::sync::Mutex

```rust
// Tauri 2.x — Standard pattern for mutable state
use std::sync::Mutex;

#[derive(Default)]
struct Counter {
    value: u32,
}

tauri::Builder::default()
    .manage(Mutex::new(Counter::default()))
    .invoke_handler(tauri::generate_handler![increment, get_count])

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

#[tauri::command]
fn get_count(state: tauri::State>) -> u32 {
    state.lock().unwrap().value
}
```

### Pattern 3: Async Commands with tokio::sync::Mutex

```rust
// Tauri 2.x — Use tokio Mutex when holding lock across .await
use tokio::sync::Mutex;

struct Database {
    connection: String,
}

#[tauri::command]
async fn save_record(
    state: tauri::State>,
    data: String,
) -> Result {
    let db = state.lock().await;
    // ... perform async database operations while holding lock ...
    Ok(())
}
```

### Pattern 4: RwLock for Read-Heavy Access

```rust
// Tauri 2.x — Multiple concurrent readers, exclusive writers
use std::sync::RwLock;

struct AppData {
    items: Vec,
}

tauri::Builder::default()
    .manage(RwLock::new(AppData { items: vec![] }))

#[tauri::command]
fn list_items(state: tauri::State>) -> Vec {
    let data = state.read().unwrap(); // Multiple readers OK
    data.items.clone()
}

#[tauri::command]
fn add_item(state: tauri::State>, item: String) {
    let mut data = state.write().unwrap(); // Exclusive access
    data.items.push(item);
}
```

### Pattern 5: State Initialization in setup()

```rust
// Tauri 2.x — State that depends on app paths or runtime info
tauri::Builder::default()
    .setup(|app| {
        let db_path = app.path().app_data_dir()?.join("data.db");
        app.manage(Database::new(&db_path)?);
        Ok(())
    })
```

### Pattern 6: Accessing State via AppHandle

```rust
// Tauri 2.x — Access state outside of commands
use std::sync::Mutex;

fn background_task(handle: tauri::AppHandle) {
    let state = handle.state::>();
    let mut counter = state.lock().unwrap();
    counter.value += 1;
}

// Safe variant — returns None if state not registered
fn maybe_access(handle: &tauri::AppHandle) {
    if let Some(state) = handle.try_state::>() {
        let counter = state.lock().unwrap();
        println!("Count: {}", counter.value);
    }
}
```

---

## Manager Trait

The `Manager` trait provides `state()` and `try_state()`. It is implemented by:

| Type | Description |
|------|-------------|
| `App` | Available in `setup()` |
| `AppHandle` | Cloneable, Send + Sync, use in threads |
| `Window` | Window instance |
| `Webview` | Webview instance |
| `WebviewWindow` | Combined window + webview |

All of these types can call `.state::()` and `.try_state::()`.

---

## Multiple State Types

Register multiple state types independently:

```rust
tauri::Builder::default()
    .manage(AppConfig { /* ... */ })
    .manage(Mutex::new(UserSession::default()))
    .manage(RwLock::new(DocumentStore::default()))
    .invoke_handler(tauri::generate_handler![
        get_config,
        login,
        get_document,
    ])

#[tauri::command]
fn get_config(config: tauri::State) -> String {
    config.api_url.clone()
}

#[tauri::command]
fn login(session: tauri::State>, user: String) {
    let mut s = session.lock().unwrap();
    s.username = user;
}
```

Each type is registered and accessed independently. There is no limit on the number of state types.

---

## Reference Links

- [references/methods.md](references/methods.md) — Complete state management API signatures
- [references/examples.md](references/examples.md) — Working code examples for common state patterns
- [references/anti-patterns.md](references/anti-patterns.md) — What NOT to do, with WHY explanations

### Official Sources

- https://v2.tauri.app/develop/state-management/
- https://docs.rs/tauri/2/tauri/struct.State.html
- https://docs.rs/tauri/2/tauri/trait.Manager.html

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Impertio-Studio](https://github.com/Impertio-Studio)
- **Source:** [Impertio-Studio/Tauri-2-Claude-Skill-Package](https://github.com/Impertio-Studio/Tauri-2-Claude-Skill-Package)
- **License:** MIT
- **Homepage:** https://github.com/OpenAEC-Foundation

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-impertio-studio-tauri-2-claude-skill-package-tauri-syntax-state
- Seller: https://agentstack.voostack.com/s/impertio-studio
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
