# Understanding the Window Management System in TUUI: Splash, Main, and Error Windows

> Explore TUUI's window management system Learn how splash main and error windows are created and managed for smooth transitions and crash recovery. Discover centralized window factories. ai-ql/tuui

- Repository: [AIQL/tuui](https://github.com/ai-ql/tuui)
- Tags: internals
- Published: 2026-02-23

---

**TUUI orchestrates splash, main, and error windows using Electron's `BrowserWindow` API through centralized factories in [`src/main/MainRunner.ts`](https://github.com/ai-ql/tuui/blob/main/src/main/MainRunner.ts), ensuring graceful startup transitions and crash recovery.**

The window management system in TUUI (part of the `ai-ql/tuui` repository) handles the complete lifecycle of application windows using Electron's native APIs. This architecture separates concerns between a lightweight splash screen, the primary application interface, and a dedicated error recovery window, all coordinated through the main process entry point at [`src/main/index.ts`](https://github.com/ai-ql/tuui/blob/main/src/main/index.ts).

## Splash Window Creation in TUUI

### Purpose and Configuration

The **splash window** provides immediate visual feedback while the main application UI initializes. According to the source code in [`src/main/MainRunner.ts`](https://github.com/ai-ql/tuui/blob/main/src/main/MainRunner.ts), the `createSplashWindow()` function constructs a small, frameless window (400 × 300 px) that stays always-on-top with a transparent background.

### Implementation Details

The factory function handles environment-specific resource loading through constants defined in [`src/main/utils/Constants.ts`](https://github.com/ai-ql/tuui/blob/main/src/main/utils/Constants.ts):

```typescript
export const createSplashWindow = async (): Promise<BrowserWindow> => {
  const splashWindow = new BrowserWindow({
    width: 400,
    height: 300,
    frame: false,
    alwaysOnTop: true,
    resizable: false,
    show: true,
    skipTaskbar: true,
    transparent: true
  })
  // Load dev or prod splash HTML
  if (Constants.IS_DEV_ENV) {
    await splashWindow.loadURL(Constants.APP_SPLASH_URL_DEV)
  } else {
    await splashWindow.loadFile(Constants.APP_SPLASH_URL_PROD)
  }
  return splashWindow
}

```

In development mode, the window loads from [`VITE_DEV_SERVER_URL/splash.html`](https://github.com/ai-ql/tuui/blob/main/VITE_DEV_SERVER_URL/splash.html), while production builds use the bundled [`../splash.html`](https://github.com/ai-ql/tuui/blob/main/../splash.html) file.

## Main Window Management

### Window Configuration and OS-Specific Features

The **main window** hosts the full TUUI application UI built with Vue. The `createMainWindow()` function in [`src/main/MainRunner.ts`](https://github.com/ai-ql/tuui/blob/main/src/main/MainRunner.ts) configures a resizable window with minimum dimensions and platform-specific title bar styling.

For Windows, Linux, and macOS, the implementation applies a hidden title bar with custom overlay colors:

```typescript
export const createMainWindow = async (): Promise<BrowserWindow> => {
  let opt: BrowserWindowConstructorOptions = {
    title: Constants.APP_NAME,
    show: false,
    width: options.width,
    height: options.height,
    minWidth: options.minWidth,
    minHeight: options.minHeight,
    useContentSize: true,
    webPreferences: Constants.DEFAULT_WEB_PREFERENCES,
    frame: true,
    ...(process.platform === 'win32' || process.platform === 'linux' || process.platform === 'darwin'
      ? {
          titleBarStyle: 'hidden',
          titleBarOverlay: {
            color: '#344767',
            symbolColor: 'white',
            height: 36
          }
        }
      : {})
  }
  const mainWindow = new BrowserWindow(opt)
  mainWindow.setMenu(null)          // disables native menu and dev-tools shortcut
  // …event handlers, tray creation, IPC init, then load UI
  if (Constants.IS_DEV_ENV) {
    await mainWindow.loadURL(Constants.APP_INDEX_URL_DEV)
  } else {
    await mainWindow.loadFile(Constants.APP_INDEX_URL_PROD)
  }
  return mainWindow
}

```

### Lifecycle and Event Handling

The main window remains hidden until the `ready-to-show` event fires, preventing visual flicker during initialization. At that point, the window is shown, focused, and temporarily set to `alwaysOnTop` to ensure it appears above the splash screen before the splash is destroyed.

Closing the main window triggers a custom `exitApp()` sequence that hides the window, destroys the instance, and calls `app.exit()` to ensure clean termination.

## Error Window Handling

### Trigger Conditions

TUUI implements a dedicated **error window** to handle renderer crashes gracefully. The system monitors two critical failure points in [`src/main/index.ts`](https://github.com/ai-ql/tuui/blob/main/src/main/index.ts):

- **`render-process-gone`**: Fires when the renderer process crashes or is killed
- **`uncaughtException`**: Catches unhandled exceptions in the main process

Both events invoke `createErrorWindow()` from [`src/main/MainRunner.ts`](https://github.com/ai-ql/tuui/blob/main/src/main/MainRunner.ts) to present a user-friendly fallback UI.

### Error Window Implementation

The error window factory accepts the existing main window instance and crash details, then constructs a replacement interface:

```typescript
export const createErrorWindow = async (
  errorWindow: BrowserWindow,
  mainWindow: BrowserWindow,
  _details?: RenderProcessGoneDetails
): Promise<BrowserWindow> => {
  if (!Constants.IS_DEV_ENV) {
    mainWindow?.hide()
  }
  errorWindow = new BrowserWindow({
    title: Constants.APP_NAME,
    show: false,
    resizable: Constants.IS_DEV_ENV,
    webPreferences: Constants.DEFAULT_WEB_PREFERENCES
  })
  errorWindow.setMenu(null)

  if (Constants.IS_DEV_ENV) {
    await errorWindow.loadURL(`${Constants.APP_INDEX_URL_DEV}#/error`)
  } else {
    await errorWindow.loadFile(Constants.APP_INDEX_URL_PROD, { hash: 'error' })
  }

  errorWindow.on('ready-to-show', () => {
    if (!Constants.IS_DEV_ENV && mainWindow && !mainWindow.isDestroyed()) {
      mainWindow.destroy()
    }
    errorWindow.show()
    errorWindow.focus()
  })
  return errorWindow
}

```

In production, the main window is hidden before the error window appears, then destroyed once the error UI is ready. The error window loads the `#/error` route, displaying a dedicated Vue component for crash recovery.

## Window Orchestration Flow

The complete window management system in TUUI follows this coordinated sequence:

1. **Application startup** – [`src/main/index.ts`](https://github.com/ai-ql/tuui/blob/main/src/main/index.ts) calls `createSplashWindow()` to display the loading screen immediately
2. **Main window preparation** – While the splash is visible, `createMainWindow()` constructs the primary UI (hidden initially)
3. **Transition** – Once the main window fires `ready-to-show`, the splash window closes and the main window appears with temporary `alwaysOnTop` focus
4. **Normal operation** – The main window handles all user interactions until closure triggers `exitApp()`
5. **Error recovery** – If `render-process-gone` or `uncaughtException` occurs, `createErrorWindow()` hides the main window and presents the error UI, ensuring the application fails gracefully rather than crashing silently

## Summary

- **TUUI's window management system** centralizes creation logic in [`src/main/MainRunner.ts`](https://github.com/ai-ql/tuui/blob/main/src/main/MainRunner.ts), exporting three factory functions: `createSplashWindow()`, `createMainWindow()`, and `createErrorWindow()`
- **Environment awareness** drives resource loading through [`src/main/utils/Constants.ts`](https://github.com/ai-ql/tuui/blob/main/src/main/utils/Constants.ts), distinguishing between development URLs and production file paths
- **Splash window** provides immediate visual feedback as a frameless, transparent 400×300px overlay that loads before the main UI
- **Main window** implements platform-specific title bar styling with hidden overlays and manages lifecycle through `ready-to-show` and custom `exitApp()` handlers
- **Error window** intercepts renderer crashes via `render-process-gone` and `uncaughtException` events, gracefully replacing the main UI with a dedicated error route

## Frequently Asked Questions

### How does TUUI's window management system handle development versus production environments?

The system uses the `Constants.IS_DEV_ENV` flag defined in [`src/main/utils/Constants.ts`](https://github.com/ai-ql/tuui/blob/main/src/main/utils/Constants.ts) to branch resource loading logic. In development, windows load from `VITE_DEV_SERVER_URL` endpoints (e.g., `http://localhost:3000/splash.html`), while production builds use `loadFile()` with relative paths to the bundled HTML files. This dual-mode approach ensures developers see live-reloaded changes while production users receive optimized static assets.

### What triggers the error window to appear in TUUI?

The error window activates through two specific event listeners in [`src/main/index.ts`](https://github.com/ai-ql/tuui/blob/main/src/main/index.ts). First, the `render-process-gone` event fires when the Chromium renderer process crashes or is terminated unexpectedly. Second, the `uncaughtException` event catches unhandled JavaScript errors in the main Node.js process. Both handlers invoke `createErrorWindow()` from [`src/main/MainRunner.ts`](https://github.com/ai-ql/tuui/blob/main/src/main/MainRunner.ts), passing the crash details and main window reference to initiate the recovery UI.

### How are the splash and main windows coordinated during application startup?

The orchestration occurs sequentially in [`src/main/index.ts`](https://github.com/ai-ql/tuui/blob/main/src/main/index.ts). First, `createSplashWindow()` returns immediately and displays the loading screen. Then `createMainWindow()` constructs the primary window in a hidden state while the splash remains visible. Once the main window emits the `ready-to-show` event, the application calls `splashWindow.close()` to destroy the loading screen, then shows and focuses the main window with a temporary `alwaysOnTop` flag to prevent visual flicker during the transition.

### Where are window configuration constants defined in the TUUI codebase?

All environment-specific URLs, dimension defaults, and web preferences are centralized in [`src/main/utils/Constants.ts`](https://github.com/ai-ql/tuui/blob/main/src/main/utils/Constants.ts). This file exports `APP_SPLASH_URL_DEV`, `APP_SPLASH_URL_PROD`, `APP_INDEX_URL_DEV`, `APP_INDEX_URL_PROD`, and `DEFAULT_WEB_PREFERENCES` used by the factory functions in [`src/main/MainRunner.ts`](https://github.com/ai-ql/tuui/blob/main/src/main/MainRunner.ts). Centralizing these values ensures consistent window behavior across development and production builds while simplifying configuration maintenance.