/desktop-multiwindow-electron
Multi-window management, WebContentsView, BaseWindow, window lifecycle, inter-window communication, state persistence
$ npx -y skills add agents-inc/skills --skill desktop-multiwindow-electron --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-electron
Context preview
The summary Claude sees to decide when to auto-load this skill.
Multi-window management, WebContentsView, BaseWindow, window lifecycle, inter-window communication, state persistence
SKILL.md
desktop-multiwindow-electron.SKILL.mdname: desktop-multiwindow-electron
description: Multi-window management, WebContentsView, BaseWindow, window lifecycle, inter-window communication, state persistence
Electron Multi-Window Patterns
> **Quick Guide:** Use `BrowserWindow` for single-view windows. Use `BaseWindow` + `WebContentsView` for multi-view layouts (tabs, split panes, panels). `BrowserView` is deprecated since Electron 30 -- migrate to `WebContentsView`. Track windows with a `Map<string, BrowserWindow>` registry. Communicate between windows via the main process or `MessagePort` for direct renderer-to-renderer channels. Persist window bounds manually or use the upcoming `windowStatePersistence` API. Always close `webContents` explicitly when using `BaseWindow` -- unlike `BrowserWindow`, it does not auto-cleanup.
---
<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 close `webContents` explicitly when destroying a `BaseWindow` -- it does not auto-cleanup like `BrowserWindow`, causing memory leaks)**
**(You MUST use `WebContentsView` instead of `BrowserView` -- `BrowserView` is deprecated since Electron 30)**
**(You MUST route all inter-window communication through the main process or `MessagePort` -- never access another window's renderer directly)**
**(You MUST validate that saved window bounds are on a visible display before restoring -- monitors may disconnect between sessions)**
</critical_requirements>
---
**Auto-detection:** multi-window, BaseWindow, WebContentsView, BrowserView migration, contentView, addChildView, removeChildView, parent window, child window, modal window, window registry, MessagePort, MessageChannelMain, window state persistence, screen API, workArea, getAllDisplays, split view, tabs, panels, window lifecycle, ready-to-show, window-all-closed
**When to use:**
- Creating multi-view layouts (tabs, split panes, embedded panels) with BaseWindow + WebContentsView
- Managing multiple BrowserWindow instances with a window registry
- Migrating from deprecated BrowserView to WebContentsView
- Setting up parent/child or modal windows
- Communicating between windows (via main process relay or MessagePort)
- Persisting and restoring window position, size, and display state
- Placing windows on specific monitors using the screen API
**When NOT to use:**
- Single-window apps with one view (`BrowserWindow` is sufficient on its own)
- Choosing a UI framework for the renderer
- IPC patterns between main and a single renderer (basic IPC is outside multi-window scope)
- Styling or layout within a single renderer
**Key patterns covered:**
- BaseWindow + WebContentsView for multi-view layouts
- BrowserView to WebContentsView migration
- Window lifecycle events (ready-to-show, close, closed)
- Parent/child and modal windows
- Window registry with Map-based tracking
- Inter-window communication via main process and MessagePort
- Window state persistence (bounds, maximized, fullscreen)
- Multi-monitor placement with screen API
---
<philosophy>
Philosophy
Electron's window model has two tiers. **BrowserWindow** is the simple path: one window, one web view, automatic lifecycle management. **BaseWindow + WebContentsView** is the flexible path: one window shell containing multiple independently managed web views, each with its own renderer process and preload script.
The key architectural decision: **use BrowserWindow for single-view windows, BaseWindow for multi-view layouts.** BaseWindow trades convenience for control -- you manage view lifecycle, bounds, and cleanup explicitly.
**When to use BaseWindow + WebContentsView:**
- Tab bars, split editors, preview panels, embedded browser views
- Any layout where multiple independent web pages share one OS window
- Applications migrating from deprecated BrowserView
**When NOT to use BaseWindow:**
- Single-view windows (BrowserWindow is simpler and handles cleanup automatically)
- Windows that only need a toolbar or status bar (a single BrowserWindow with HTML layout is sufficient)
</philosophy>
---
<patterns>
Core Patterns
Pattern 1: BaseWindow with WebContentsView
BaseWindow is the window shell; WebContentsView instances are the content. Each view has its own renderer process and preload script.
const { BaseWindow, WebContentsView } = require("electron");
const win = new BaseWindow({ width: 1200, height: 800 });
const sidebar = new WebContentsView({
webPreferences: { preload: path.join(__dirname, "preload.js") },
});
const main = new WebContentsView({
webPreferences: { preload: path.join(__dirname, "preload.js") },
});
win.contentView.addChildView(sidebar);
win.contentView.addChildView(main);
const SIDEBAR_WIDTH = 250;
sidebar.setBounds({ x: 0, y: 0, width: SIDEBAR_WIDTH, height: 800 });
main.setBounds({ x: SIDEBAR_WIDTH, y: 0, width: 950, height: 800 });
sidebar.webContents.loadFile("sidebar.html");
main.webContents.loadFile("main.html");**Key point:** Each WebContentsView needs its own `webPreferences` and preload script. BaseWindow has no `webContents` of its own. See [examples/core.md](examples/core.md) for complete split-view and tab examples with resize handling.
---
Pattern 2: BrowserView to WebContentsView Migration
BrowserView is deprecated since Electron 30. Migration is straightforward -- constructors have the same shape.
| Deprecated (BrowserView) | Replacement (WebContentsView) | | ------------------------------------------- | ---------------------------------------------------------- | | `new BrowserView(opts)` | `new WebContentsView(opts)` | | `win.addBrowserView(view)` | `win.contentView.addChildView(view)` | | `win.removeBrowserView(view)` | `win.contentView.re
Read more
name: desktop-multiwindow-electron description: Multi-window management, WebContentsView, BaseWindow, window lifecycle, inter-window communication, state persistence
Electron Multi-Window Patterns
> **Quick Guide:** Use `BrowserWindow` for single-view windows. Use `BaseWindow` + `WebContentsView` for multi-view layouts (tabs, split panes, panels). `BrowserView` is deprecated since Electron 30 -- migrate to `WebContentsView`. Track windows with a `Map<string, BrowserWindow>` registry. Communicate between windows via the main process or `MessagePort` for direct renderer-to-renderer channels. Persist window bounds manually or use the upcoming `windowStatePersistence` API. Always close `webContents` explicitly when using `BaseWindow` -- unlike `BrowserWindow`, it does not auto-cleanup.
---
<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 close `webContents` explicitly when destroying a `BaseWindow` -- it does not auto-cleanup like `BrowserWindow`, causing memory leaks)**
**(You MUST use `WebContentsView` instead of `BrowserView` -- `BrowserView` is deprecated since Electron 30)**
**(You MUST route all inter-window communication through the main process or `MessagePort` -- never access another window's renderer directly)**
**(You MUST validate that saved window bounds are on a visible display before restoring -- monitors may disconnect between sessions)**
</critical_requirements>
---
**Auto-detection:** multi-window, BaseWindow, WebContentsView, BrowserView migration, contentView, addChildView, removeChildView, parent window, child window, modal window, window registry, MessagePort, MessageChannelMain, window state persistence, screen API, workArea, getAllDisplays, split view, tabs, panels, window lifecycle, ready-to-show, window-all-closed
**When to use:**
- Creating multi-view layouts (tabs, split panes, embedded panels) with BaseWindow + WebContentsView
- Managing multiple BrowserWindow instances with a window registry
- Migrating from deprecated BrowserView to WebContentsView
- Setting up parent/child or modal windows
- Communicating between windows (via main process relay or MessagePort)
- Persisting and restoring window position, size, and display state
- Placing windows on specific monitors using the screen API
**When NOT to use:**
- Single-window apps with one view (`BrowserWindow` is sufficient on its own)
- Choosing a UI framework for the renderer
- IPC patterns between main and a single renderer (basic IPC is outside multi-window scope)
- Styling or layout within a single renderer
**Key patterns covered:**
- BaseWindow + WebContentsView for multi-view layouts
- BrowserView to WebContentsView migration
- Window lifecycle events (ready-to-show, close, closed)
- Parent/child and modal windows
- Window registry with Map-based tracking
- Inter-window communication via main process and MessagePort
- Window state persistence (bounds, maximized, fullscreen)
- Multi-monitor placement with screen API
---
<philosophy>
Philosophy
Electron's window model has two tiers. **BrowserWindow** is the simple path: one window, one web view, automatic lifecycle management. **BaseWindow + WebContentsView** is the flexible path: one window shell containing multiple independently managed web views, each with its own renderer process and preload script.
The key architectural decision: **use BrowserWindow for single-view windows, BaseWindow for multi-view layouts.** BaseWindow trades convenience for control -- you manage view lifecycle, bounds, and cleanup explicitly.
**When to use BaseWindow + WebContentsView:**
- Tab bars, split editors, preview panels, embedded browser views
- Any layout where multiple independent web pages share one OS window
- Applications migrating from deprecated BrowserView
**When NOT to use BaseWindow:**
- Single-view windows (BrowserWindow is simpler and handles cleanup automatically)
- Windows that only need a toolbar or status bar (a single BrowserWindow with HTML layout is sufficient)
</philosophy>
---
<patterns>
Core Patterns
Pattern 1: BaseWindow with WebContentsView
BaseWindow is the window shell; WebContentsView instances are the content. Each view has its own renderer process and preload script.
const { BaseWindow, WebContentsView } = require("electron");
const win = new BaseWindow({ width: 1200, height: 800 });
const sidebar = new WebContentsView({
webPreferences: { preload: path.join(__dirname, "preload.js") },
});
const main = new WebContentsView({
webPreferences: { preload: path.join(__dirname, "preload.js") },
});
win.contentView.addChildView(sidebar);
win.contentView.addChildView(main);
const SIDEBAR_WIDTH = 250;
sidebar.setBounds({ x: 0, y: 0, width: SIDEBAR_WIDTH, height: 800 });
main.setBounds({ x: SIDEBAR_WIDTH, y: 0, width: 950, height: 800 });
sidebar.webContents.loadFile("sidebar.html");
main.webContents.loadFile("main.html");**Key point:** Each WebContentsView needs its own `webPreferences` and preload script. BaseWindow has no `webContents` of its own. See [examples/core.md](examples/core.md) for complete split-view and tab examples with resize handling.
---
Pattern 2: BrowserView to WebContentsView Migration
BrowserView is deprecated since Electron 30. Migration is straightforward -- constructors have the same shape.
| Deprecated (BrowserView) | Replacement (WebContentsView) | | ------------------------------------------- | ---------------------------------------------------------- | | `new BrowserView(opts)` | `new WebContentsView(opts)` | | `win.addBrowserView(view)` | `win.contentView.addChildView(view)` | | `win.removeBrowserView(view)` | `win.contentView.re
Showing 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

