/desktop-multiwindow-tauri
Tauri 2.x multi-window creation, event system, window state persistence, parent/child and modal windows
$ npx -y skills add agents-inc/skills --skill desktop-multiwindow-tauri --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/desktop-multiwindow-tauri
Context preview
The summary Claude sees to decide when to auto-load this skill.
Tauri 2.x multi-window creation, event system, window state persistence, parent/child and modal windows
SKILL.md
desktop-multiwindow-tauri.SKILL.mdname: desktop-multiwindow-tauri
description: Tauri 2.x multi-window creation, event system, window state persistence, parent/child and modal windows
Tauri Multi-Window & Events
> **Quick Guide:** Create windows from JS with `new WebviewWindow(label, options)` or from Rust with `WebviewWindowBuilder`. Communicate across windows using events: `emit()` broadcasts globally, `emitTo(label, event, payload)` targets a specific window, `emit_filter()` targets multiple windows by predicate. Always call the unlisten function returned by `listen()`. Use `tauri-plugin-window-state` to persist window position/size across sessions. Window labels must be unique and are used for both event targeting and permission scoping. > > **Current version:** Tauri 2.x (stable). Multi-webview in a single window requires the `unstable` feature flag.
---
<critical_requirements>
CRITICAL: Before Using This Skill
> **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)
**(You MUST give every window a unique label -- labels identify windows for event targeting, permissions, and retrieval)**
**(You MUST always call the unlisten function returned by `listen()` / `once()` -- leaked listeners cause memory leaks in long-running apps)**
**(You MUST check if a window already exists before creating it -- duplicate labels cause runtime errors)**
**(You MUST add window labels to capability file `windows` array -- windows without permissions cannot use plugins or core APIs)**
**(You MUST use `@tauri-apps/api/event` for global events and `@tauri-apps/api/webviewWindow` for window-scoped events -- mixing them causes missed events)**
</critical_requirements>
---
**Auto-detection:** WebviewWindow, WebviewWindowBuilder, emit_to, emitTo, emit_filter, EventTarget, window label, multi-window, onCloseRequested, tauri-plugin-window-state, parent window, modal window, WebviewBuilder, add_child, getCurrentWebviewWindow, window.listen, window.emit, cross-window communication
**When to use:**
- Creating secondary windows (settings, preferences, about, detached panels)
- Communicating between windows via the Tauri event system
- Handling window close confirmation (unsaved changes dialogs)
- Persisting window size/position across app restarts
- Setting up parent/child or modal window relationships
- Building multi-panel layouts with multiple webviews in a single window
**When NOT to use:**
- Single-window apps with no inter-window communication (use the base Tauri framework skill)
- General Tauri commands, IPC, or plugin setup (use the base Tauri framework skill)
- Frontend framework state management within a single window (use respective framework skills)
**Key patterns covered:**
- Window creation from JS and Rust ([examples/core.md](examples/core.md))
- Event system: emit, emitTo, emit_filter for targeted messaging ([examples/core.md](examples/core.md))
- Cross-window state synchronization via events ([examples/core.md](examples/core.md))
- Window close confirmation with onCloseRequested ([examples/core.md](examples/core.md))
- Window state persistence with tauri-plugin-window-state ([examples/persistence.md](examples/persistence.md))
- Parent/child windows and modal dialogs ([examples/advanced.md](examples/advanced.md))
- Multi-webview in a single window (unstable) ([examples/advanced.md](examples/advanced.md))
**Detailed resources:**
- [examples/core.md](examples/core.md) - Window creation, event system, close confirmation, cross-window sync
- [examples/persistence.md](examples/persistence.md) - Window state plugin setup, manual save/restore, StateFlags
- [examples/advanced.md](examples/advanced.md) - Parent/child windows, modals, multi-webview layouts
- [reference.md](reference.md) - API quick reference, event method comparison, decision framework
---
<philosophy>
Philosophy
Tauri's multi-window architecture is built on two key concepts: **window labels** for identification and **events** for communication.
Every window has a unique string label assigned at creation. This label is used everywhere: event targeting with `emitTo`, permission scoping in capability files, and retrieval with `app.get_webview_window(label)`. Labels are the window's address.
The event system follows a pub-sub model with three tiers of targeting:
1. **Global** (`emit`) -- all listeners in all windows receive the event 2. **Targeted** (`emitTo`) -- only listeners in the specified window receive the event 3. **Filtered** (`emit_filter`) -- listeners matching a predicate receive the event
**When to use multi-window patterns:**
- App needs separate UI surfaces (settings panel, file viewer, log output)
- Need to decouple UI concerns into independent windows
- Need modal dialogs that block interaction with the parent window
- Need persistent panel layouts (IDE-style split views)
**When NOT to use multi-window:**
- A tabbed interface within a single window handles the use case
- The secondary UI is a simple overlay/modal that lives in the same DOM
- You only need to show/hide sections of a single-page app
</philosophy>
---
<patterns>
Core Patterns
Pattern 1: Window Creation
Create windows from JavaScript or Rust. Always check if the window exists first to avoid duplicate-label errors.
import { WebviewWindow } from "@tauri-apps/api/webviewWindow";
const SETTINGS_WINDOW_LABEL = "settings";
const SETTINGS_WIDTH = 600;
const SETTINGS_HEIGHT = 400;
// Check if already open, focus it instead of creating duplicate
const existing = await WebviewWindow.getByLabel(SETTINGS_WINDOW_LABEL);
if (existing) {
await existing.setFocus();
return;
}
const settingsWindow = new WebviewWindow(SETTINGS_WINDOW_LABEL, {
url: "settings.html",
title: "Settings",
width: SETTINGS_WIDTH,
height: SETTINGS_HEIGHT,
resizable: false,
center: true,
});
settingsWindow.once("tauri://created", () => {
console.log("Settings window creatRead more
name: desktop-multiwindow-tauri description: Tauri 2.x multi-window creation, event system, window state persistence, parent/child and modal windows
Tauri Multi-Window & Events
> **Quick Guide:** Create windows from JS with `new WebviewWindow(label, options)` or from Rust with `WebviewWindowBuilder`. Communicate across windows using events: `emit()` broadcasts globally, `emitTo(label, event, payload)` targets a specific window, `emit_filter()` targets multiple windows by predicate. Always call the unlisten function returned by `listen()`. Use `tauri-plugin-window-state` to persist window position/size across sessions. Window labels must be unique and are used for both event targeting and permission scoping. > > **Current version:** Tauri 2.x (stable). Multi-webview in a single window requires the `unstable` feature flag.
---
<critical_requirements>
CRITICAL: Before Using This Skill
> **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)
**(You MUST give every window a unique label -- labels identify windows for event targeting, permissions, and retrieval)**
**(You MUST always call the unlisten function returned by `listen()` / `once()` -- leaked listeners cause memory leaks in long-running apps)**
**(You MUST check if a window already exists before creating it -- duplicate labels cause runtime errors)**
**(You MUST add window labels to capability file `windows` array -- windows without permissions cannot use plugins or core APIs)**
**(You MUST use `@tauri-apps/api/event` for global events and `@tauri-apps/api/webviewWindow` for window-scoped events -- mixing them causes missed events)**
</critical_requirements>
---
**Auto-detection:** WebviewWindow, WebviewWindowBuilder, emit_to, emitTo, emit_filter, EventTarget, window label, multi-window, onCloseRequested, tauri-plugin-window-state, parent window, modal window, WebviewBuilder, add_child, getCurrentWebviewWindow, window.listen, window.emit, cross-window communication
**When to use:**
- Creating secondary windows (settings, preferences, about, detached panels)
- Communicating between windows via the Tauri event system
- Handling window close confirmation (unsaved changes dialogs)
- Persisting window size/position across app restarts
- Setting up parent/child or modal window relationships
- Building multi-panel layouts with multiple webviews in a single window
**When NOT to use:**
- Single-window apps with no inter-window communication (use the base Tauri framework skill)
- General Tauri commands, IPC, or plugin setup (use the base Tauri framework skill)
- Frontend framework state management within a single window (use respective framework skills)
**Key patterns covered:**
- Window creation from JS and Rust ([examples/core.md](examples/core.md))
- Event system: emit, emitTo, emit_filter for targeted messaging ([examples/core.md](examples/core.md))
- Cross-window state synchronization via events ([examples/core.md](examples/core.md))
- Window close confirmation with onCloseRequested ([examples/core.md](examples/core.md))
- Window state persistence with tauri-plugin-window-state ([examples/persistence.md](examples/persistence.md))
- Parent/child windows and modal dialogs ([examples/advanced.md](examples/advanced.md))
- Multi-webview in a single window (unstable) ([examples/advanced.md](examples/advanced.md))
**Detailed resources:**
- [examples/core.md](examples/core.md) - Window creation, event system, close confirmation, cross-window sync
- [examples/persistence.md](examples/persistence.md) - Window state plugin setup, manual save/restore, StateFlags
- [examples/advanced.md](examples/advanced.md) - Parent/child windows, modals, multi-webview layouts
- [reference.md](reference.md) - API quick reference, event method comparison, decision framework
---
<philosophy>
Philosophy
Tauri's multi-window architecture is built on two key concepts: **window labels** for identification and **events** for communication.
Every window has a unique string label assigned at creation. This label is used everywhere: event targeting with `emitTo`, permission scoping in capability files, and retrieval with `app.get_webview_window(label)`. Labels are the window's address.
The event system follows a pub-sub model with three tiers of targeting:
1. **Global** (`emit`) -- all listeners in all windows receive the event 2. **Targeted** (`emitTo`) -- only listeners in the specified window receive the event 3. **Filtered** (`emit_filter`) -- listeners matching a predicate receive the event
**When to use multi-window patterns:**
- App needs separate UI surfaces (settings panel, file viewer, log output)
- Need to decouple UI concerns into independent windows
- Need modal dialogs that block interaction with the parent window
- Need persistent panel layouts (IDE-style split views)
**When NOT to use multi-window:**
- A tabbed interface within a single window handles the use case
- The secondary UI is a simple overlay/modal that lives in the same DOM
- You only need to show/hide sections of a single-page app
</philosophy>
---
<patterns>
Core Patterns
Pattern 1: Window Creation
Create windows from JavaScript or Rust. Always check if the window exists first to avoid duplicate-label errors.
import { WebviewWindow } from "@tauri-apps/api/webviewWindow";
const SETTINGS_WINDOW_LABEL = "settings";
const SETTINGS_WIDTH = 600;
const SETTINGS_HEIGHT = 400;
// Check if already open, focus it instead of creating duplicate
const existing = await WebviewWindow.getByLabel(SETTINGS_WINDOW_LABEL);
if (existing) {
await existing.setFocus();
return;
}
const settingsWindow = new WebviewWindow(SETTINGS_WINDOW_LABEL, {
url: "settings.html",
title: "Settings",
width: SETTINGS_WIDTH,
height: SETTINGS_HEIGHT,
resizable: false,
center: true,
});
settingsWindow.once("tauri://created", () => {
console.log("Settings window creatShowing the first part of this file.
The official skills marketplace for Agents Inc. 150+ 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?
Repo: agents-inc/skills
Other skills on agents-inc-skills.
- /ai-infrastructure-huggingface-inference
Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation, audio transcription, translation, summarization, and Inference Endpoints
Open skill - /ai-infrastructure-litellm
LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking, virtual keys, and production deployment
Open skill - /ai-infrastructure-modal
Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client patterns
Open skill - /ai-infrastructure-ollama
Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output, model management, and OpenAI-compatible endpoint
Open skill - /ai-infrastructure-replicate
Replicate SDK patterns for TypeScript/Node.js -- client setup, predictions, streaming, webhooks, file handling, model versioning, deployments, and training
Open skill - /ai-infrastructure-together-ai
Together AI SDK patterns for TypeScript — client setup, chat completions, streaming, structured output, function calling, embeddings, image generation, fine-tuning, and OpenAI-compatible endpoints
Open skill

