> ## Documentation Index
> Fetch the complete documentation index at: https://webview.js.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Opening and Managing Multiple Windows in WebviewJS

> Open, track, and manage multiple BrowserWindows in a single application. Learn show/hide lifecycle, child popup windows, and cross-window event handling.

WebviewJS drives all windows from a single event loop pump started by `app.run()`. Each window is an independent `BrowserWindow` instance with its own embedded `Webview`. You can create as many windows as you need before or after calling `app.run()`, and all of them share the same non-blocking event loop — ordinary Node timers and I/O continue running alongside native window events.

***

## Opening multiple windows

Create each window with `app.createBrowserWindow()` and attach a webview. All windows start together when the shared event loop runs.

```js theme={null}
import { Application } from '@webviewjs/webview';

const app = new Application();

function createWindow(title, url) {
  const win = app.createBrowserWindow({ title, width: 900, height: 600 });
  const webview = win.createWebview({ url });
  return { win, webview };
}

const docs   = createWindow('Docs',   'https://example.com/docs');
const editor = createWindow('Editor', 'https://example.com/editor');

app.run();
```

Both windows share the same event loop. There is no need to synchronise them manually.

***

## Tracking windows

<Tip>
  Assign a stable string or numeric ID to each window when you create it and
  store it in a `Map`. Check the Map before creating a duplicate, and call
  `win.show()` to bring an existing window to the foreground instead.
</Tip>

```js theme={null}
import { Application } from '@webviewjs/webview';

const app = new Application();
const windows = new Map(); // id → { win, webview }

function openWindow(id, url) {
  if (windows.has(id)) {
    // Window already exists — bring it to the front
    windows.get(id).win.show();
    return;
  }

  const win = app.createBrowserWindow({ title: id, width: 800, height: 600 });
  const webview = win.createWebview({ url });
  windows.set(id, { win, webview });
}

openWindow('main',     'https://example.com');
openWindow('settings', 'https://example.com/settings');

app.run();
```

***

## Child (popup) windows

Use `app.createChildBrowserWindow()` for dialogs, palettes, and tool panels that should be positioned relative to a parent window. Child windows behave like independent windows but share the parent's native context.

```js theme={null}
const app = new Application();
const main = app.createBrowserWindow({ title: 'Main Window', width: 1000, height: 700 });
main.createWebview({ url: 'app://localhost/index.html' });

// Open a Settings popup
const settings = app.createChildBrowserWindow({
  title:  'Settings',
  width:  400,
  height: 300,
});
settings.createWebview({ url: 'app://localhost/settings.html' });

app.run();
```

***

## Show and hide instead of destroy

When the user clicks the OS close button on a window, the WebviewJS runtime **hides** the window rather than destroying it. The native resources remain allocated, and you can show the window again at any time without re-creating it.

```js theme={null}
// Toggle visibility based on current state
function toggleWindow(win) {
  win.setVisible(!win.isVisible());
}

// Or use the explicit helpers
win.show();
win.hide();
```

This pattern is especially useful for persistent tool windows or settings panels that users open and close frequently.

***

## Window lifecycle events

Listen for lifecycle events on the `Application` instance to respond to window and application close requests.

```js theme={null}
app.on('window-close-requested', () => {
  // One window has been hidden by the runtime.
  // Individual window references remain valid — call win.show() to restore.
  console.log('A window was hidden.');
});

app.on('application-close-requested', () => {
  // Every tracked window is now hidden.
  // This is the right place to call app.exit() for a clean shutdown.
  console.log('All windows hidden — exiting.');
  app.exit();
});
```

`window-close-requested` fires each time a single window is hidden. `application-close-requested` fires once all windows are hidden. If you do not call `app.exit()` inside `application-close-requested`, the application continues running (useful for tray-only apps).

***

## Disposal

Call `win.dispose()` to immediately release a window and its webview before calling `app.exit()`. Disposal is idempotent — calling it more than once is safe.

```js theme={null}
// Explicit disposal
win.dispose();

// Or use the using-declaration with Symbol.dispose (Node.js >= 18 / ES2022)
{
  using win = app.createBrowserWindow({ title: 'Temporary' });
  win.createWebview({ html: '<p>Hello</p>' });
  // win.dispose() is called automatically when the block exits
}
```

`app.exit()` disposes all root-owned windows and webviews in shutdown order. After disposal, `win.isDisposed()` returns `true` and further method calls throw a disposed error.

<Note>
  Keep a strong JavaScript reference to each `BrowserWindow` and `Webview` for
  as long as you need to call their methods or retain their event listeners.
  Dropping the last reference allows the garbage collector to run finalizers,
  which may trigger unexpected disposal.
</Note>

***

## Related pages

* [Menus](/guides/menus) — per-window and global menu bars
* [IPC Messaging](/guides/ipc-messaging) — communicating between windows and Node.js
* [BrowserWindow API reference](/api/browser-window) — full method signatures for `show`, `hide`, `setVisible`, `dispose`, and window options
