Open-Source Wikis

/

Tauri

/

Systems

/

Event system

tauri-apps/tauri

Event system

The event system is the loose-coupling counterpart to commands. Where a command is a request/response pair tied to a single function, an event is fire-and-forget broadcast that any number of listeners can subscribe to. Both Rust and JS sit on the same bus.

Concepts

  • Event — a name (string) plus a serde-serialisable payload.
  • Listener — a callback registered with listen (Rust or JS) that receives every matching event.
  • Target — global, a specific webview, a webview-window, or a window. Restricting target makes broadcasts scoped.
  • One-shotonce listeners auto-unsubscribe after the first delivery.

Surfaces

From JS

import { listen, emit, once } from '@tauri-apps/api/event';

const unlisten = await listen<MyPayload>('user-logged-in', (event) => {});
await emit('refresh');
await once('updater://download-finished', () => {});
unlisten();

The JS API lives in packages/api/src/event.ts.

From Rust

use tauri::{Manager, AppHandle};

app_handle.emit("refresh", ())?;
let id = app_handle.listen_any("user-logged-in", |evt| {});
app_handle.unlisten(id);

The Manager trait exposes emit, emit_to, listen_any, listen, unlisten, once. Webview and WebviewWindow carry scoped variants (Webview::emit, etc.).

Flow

graph LR
    JSemit["JS emit('e', p)"] -->|"command plugin:event|emit"| RustBus["AppManager event bus"]
    RustBus -->|"deliver to JS subscribers"| JSlisteners["JS listen handlers"]
    RustBus --> RustListeners["Rust listen_any handlers"]
    RustEmit["Rust emit('e', p)"] --> RustBus

Internally, JS-emitted events are normal IPC messages routed through plugin:event|emit. The Rust manager dedupes, applies any target filter, and fans out to:

  • Native Rust listeners registered via listen_any / listen.
  • WebView-side listeners registered via listen (the manager calls webview.eval(format!("__TAURI__.event.dispatch(...)"))).

crates/tauri/src/event/ holds the bus implementation, listener bookkeeping, and the message types. ACL gates this through the core:event:default permission and friends in crates/tauri/permissions/event/.

Built-in events

A handful of events are emitted by the runtime:

Event When
tauri://close-requested A close request arrived for a window.
tauri://destroyed A webview was destroyed.
tauri://focus / blur Focus changes.
tauri://drop / drag-over OS-native drag-and-drop into the webview.
tauri://resize / move Window geometry changes.
tauri://theme-changed OS theme switch.
tauri://scale-change DPI change.
tauri://menu Menu activations (when wired to events).
tauri://update-* Updater plugin events (in tauri-plugin-updater).

Plugins commonly emit their own events under their own prefix (e.g. download-progress from a download plugin).

Files at a glance

File Role
crates/tauri/src/event/ Rust bus, listener registry, EventName types
crates/tauri/permissions/event/ Built-in ACL permissions for emit/listen
crates/tauri/src/manager/mod.rs Hosts the global listener table
packages/api/src/event.ts JS-side listen/emit/once and Event type

Cross-references

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Event system – Tauri wiki | Factory