# Tauri Syntax Events

> >

- **Type:** Skill
- **Install:** `agentstack add skill-impertio-studio-tauri-2-claude-skill-package-tauri-syntax-events`
- **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-events
- **Website:** https://github.com/OpenAEC-Foundation

## Install

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

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

## About

# tauri-syntax-events

## Quick Reference

### Rust Event Traits (Tauri 2.x)

| Trait | Implemented By | Purpose |
|-------|---------------|---------|
| `Emitter` | `App`, `AppHandle`, `Webview`, `WebviewWindow`, `Window` | Send events |
| `Listener` | `App`, `AppHandle`, `Webview`, `WebviewWindow`, `Window` | Receive events |

### Emitter Methods

| Method | Scope | Description |
|--------|-------|-------------|
| `emit(event, payload)` | Global | Broadcast to ALL listeners |
| `emit_str(event, payload)` | Global | Broadcast with pre-serialized JSON string |
| `emit_to(target, event, payload)` | Targeted | Send to a specific window/webview label |
| `emit_filter(event, payload, filter_fn)` | Filtered | Send to targets matching a predicate |

### Listener Methods

| Method | Fires | Returns |
|--------|-------|---------|
| `listen(event, handler)` | Every time | `EventId` |
| `once(event, handler)` | Once, then auto-removes | `EventId` |
| `listen_any(event, handler)` | Every time, any source | `EventId` |
| `once_any(event, handler)` | Once, any source | `EventId` |
| `unlisten(id)` | N/A | `()` |

### Frontend Event API (TypeScript)

| Function | Import | Description |
|----------|--------|-------------|
| `listen(event, handler, options?)` | `@tauri-apps/api/event` | Listen for events, returns `Promise` |
| `once(event, handler, options?)` | `@tauri-apps/api/event` | Listen once, returns `Promise` |
| `emit(event, payload?)` | `@tauri-apps/api/event` | Broadcast event globally |
| `emitTo(target, event, payload?)` | `@tauri-apps/api/event` | Send event to specific target |

### TauriEvent Built-in Events

| Member | Value |
|--------|-------|
| `WINDOW_RESIZED` | `"tauri://resize"` |
| `WINDOW_MOVED` | `"tauri://move"` |
| `WINDOW_CLOSE_REQUESTED` | `"tauri://close-requested"` |
| `WINDOW_DESTROYED` | `"tauri://destroyed"` |
| `WINDOW_FOCUS` | `"tauri://focus"` |
| `WINDOW_BLUR` | `"tauri://blur"` |
| `WINDOW_SCALE_FACTOR_CHANGED` | `"tauri://scale-change"` |
| `WINDOW_THEME_CHANGED` | `"tauri://theme-changed"` |
| `WINDOW_CREATED` | `"tauri://window-created"` |
| `WEBVIEW_CREATED` | `"tauri://webview-created"` |
| `DRAG_ENTER` | `"tauri://drag-enter"` |
| `DRAG_OVER` | `"tauri://drag-over"` |
| `DRAG_DROP` | `"tauri://drag-drop"` |
| `DRAG_LEAVE` | `"tauri://drag-leave"` |

---

## Critical Warnings

**NEVER** forget `Clone` on event payload structs — `emit()` requires `Serialize + Clone`. Omitting `Clone` causes a compile error that does not clearly indicate the source.

**NEVER** use special characters in event names — only alphanumeric, `-`, `/`, `:`, and `_` are allowed. Other characters cause a runtime panic.

**NEVER** forget to call the unlisten function in frontend components — this causes memory leaks. In React, ALWAYS clean up in the `useEffect` return function.

**NEVER** forget to `await` the `listen()` call in TypeScript — `listen()` returns `Promise`, not `UnlistenFn` directly.

**ALWAYS** import the `Emitter` trait (`use tauri::Emitter;`) before calling `emit()` in Rust — the method is not available without the trait import.

**ALWAYS** import the `Listener` trait (`use tauri::Listener;`) before calling `listen()` in Rust.

---

## Essential Patterns

### Pattern 1: Rust to Frontend (Emitter)

```rust
// Tauri 2.x — Broadcast from Rust to all frontend listeners
use tauri::Emitter;

#[derive(Clone, serde::Serialize)]
struct ProgressUpdate {
    task_id: String,
    percent: f64,
    message: String,
}

// In a command or setup hook:
app_handle.emit("progress", ProgressUpdate {
    task_id: "download-1".into(),
    percent: 45.5,
    message: "Downloading file...".into(),
})?;
```

### Pattern 2: Frontend Listening

```typescript
// Tauri 2.x — Listen in TypeScript
import { listen } from '@tauri-apps/api/event';

interface ProgressUpdate {
  taskId: string;
  percent: number;
  message: string;
}

const unlisten = await listen('progress', (event) => {
  console.log(`${event.payload.taskId}: ${event.payload.percent}%`);
});

// When done:
unlisten();
```

### Pattern 3: Frontend to Rust (Emit + Listen)

```typescript
// Tauri 2.x — Frontend emits
import { emit } from '@tauri-apps/api/event';

await emit('user-action', { action: 'save', documentId: 42 });
```

```rust
// Tauri 2.x — Rust listens (typically in setup hook)
use tauri::Listener;

app.listen("user-action", |event| {
    println!("User action: {:?}", event.payload());
});
```

### Pattern 4: Targeted Emission

```rust
// Tauri 2.x — Emit to specific window
use tauri::Emitter;

app_handle.emit_to("main", "notification", "Update available")?;

// Emit with filter
app_handle.emit_filter("sync", payload, |target| {
    matches!(target, tauri::EventTarget::WebviewWindow { label } if label != "settings")
})?;
```

```typescript
// Tauri 2.x — Frontend targeted emit
import { emitTo } from '@tauri-apps/api/event';

await emitTo('settings', 'config-changed', { key: 'theme', value: 'dark' });
```

### Pattern 5: React Cleanup Pattern

```typescript
// Tauri 2.x — Correct cleanup in React useEffect
import { listen } from '@tauri-apps/api/event';

useEffect(() => {
  let unlisten: (() => void) | undefined;

  listen('update', (event) => {
    setState(event.payload);
  }).then((fn) => { unlisten = fn; });

  return () => {
    if (unlisten) unlisten();
  };
}, []);
```

### Pattern 6: Once (Single-Fire Listener)

```rust
// Tauri 2.x — Rust: listen once, auto-removes
use tauri::Listener;

app.once("initialization-complete", |event| {
    println!("App initialized: {:?}", event.payload());
});
```

```typescript
// Tauri 2.x — TypeScript: listen once
import { once } from '@tauri-apps/api/event';

await once('app-ready', (event) => {
  console.log('App initialized:', event.payload);
});
```

---

## TypeScript Event Types

```typescript
type EventName = string; // alphanumeric, hyphens, slashes, colons, underscores
type EventCallback = (event: Event) => void;
type UnlistenFn = () => void;

interface Event {
  event: EventName;
  id: number;
  payload: T;
}

interface Options {
  target?: string | EventTarget;
}

type EventTarget =
  | { kind: 'Any' }
  | { kind: 'AnyLabel'; label: string }
  | { kind: 'Window'; label: string }
  | { kind: 'Webview'; label: string }
  | { kind: 'WebviewWindow'; label: string };
```

---

## Permissions Required

Events require `core:event:default` in the capability file:

```json
{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "default",
  "windows": ["main"],
  "permissions": [
    "core:event:default"
  ]
}
```

---

## Reference Links

- [references/methods.md](references/methods.md) — Complete Emitter and Listener trait signatures
- [references/examples.md](references/examples.md) — Working code examples for common event scenarios
- [references/anti-patterns.md](references/anti-patterns.md) — What NOT to do, with WHY explanations

### Official Sources

- https://v2.tauri.app/develop/calling-rust/#event-system
- https://docs.rs/tauri/2/tauri/trait.Emitter.html
- https://docs.rs/tauri/2/tauri/trait.Listener.html
- https://v2.tauri.app/reference/javascript/api/namespaceevent/

## 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-events
- 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%.
