# Electron-Based Node UI for Azeroth Auction Assassin (AAA): Architecture and Implementation Guide

> Explore the Electron-based Node UI for Azeroth Auction Assassin (AAA). Learn its architecture and implementation for WoW auction house scans. Get a responsive, cross-platform desktop app.

- Repository: [FF14 Advanced Market Search/azerothauctionassassin](https://github.com/ff14-advanced-market-search/azerothauctionassassin)
- Tags: architecture
- Published: 2026-03-01

---

**The Electron-based Node UI for AAA is a cross-platform desktop application built with Electron and Node.js that provides a secure, responsive interface for configuring and monitoring World of Warcraft auction house scans through a main process, renderer process, and preload script architecture.**

The `ff14-advanced-market-search/azerothauctionassassin` repository ships this lightweight desktop front-end to give users a native application experience for managing auction sniping rules. The UI runs as two distinct processes—a privileged main process and a sandboxed renderer process—communicating through a tightly controlled IPC bridge.

## Architecture Overview

The Electron-based Node UI for AAA follows the standard Electron multi-process model to balance security with functionality.

### Main Process

The main process controls the application lifecycle, creates windows, and handles privileged file-system or network work. In [`node-ui/main.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/main.js), the application boots Electron, creates the `BrowserWindow`, defines data directories, sets up IPC handlers, and runs the alert engine.

Key responsibilities include:
- Reading the current version from [`package.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/package.json) (`CURRENT_VERSION`)
- Managing configurable data directories via `getDataDir()` and static assets via `getStaticDir()`
- Registering IPC handlers for file operations, backup/restore, and alert engine control
- Loading [`node-ui/mega-alerts.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/mega-alerts.js) to execute auction scans in-process

### Renderer Process

The renderer process renders HTML/CSS/JS, interacts with the user, and communicates with the main process via `ipcRenderer`. The [`node-ui/renderer.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/renderer.js) file binds UI elements (buttons, forms, navigation) to IPC calls, updates the view, and logs output.

The renderer initializes the UI on `DOMContentLoaded`, calling `window.electronAPI.loadState()` to populate forms and display the current data directory and zoom level. It manages navigation between views, handles form submissions, and displays log output from the alert engine.

### Preload Script

The preload script safely exposes a limited API to the renderer while keeping Node integration disabled. In [`node-ui/preload.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/preload.js), the script registers `window.electronAPI` methods that forward calls to `ipcRenderer`:

```javascript
const { contextBridge, ipcRenderer } = require("electron")

contextBridge.exposeInMainWorld("electronAPI", {
  loadState: () => ipcRenderer.invoke("load-state"),
  saveMegaData: (payload) => ipcRenderer.invoke("save-mega-data", payload),
  startMega: () => ipcRenderer.invoke("run-mega"),
  stopMega: () => ipcRenderer.invoke("stop-mega"),
  // … plus all other UI actions
})

```

This architecture ensures that because `nodeIntegration` is off and `contextIsolation` is enabled, the renderer can only call the whitelisted methods, preventing arbitrary Node access.

## Key Components and File Structure

The Electron-based Node UI for AAA organizes its source code under the `node-ui/` directory with clear separation of concerns:

| File | Role |
|------|------|
| [`node-ui/main.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/main.js) | Main process: creates window, defines data paths, registers IPC, runs alerts. |
| [`node-ui/preload.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/preload.js) | Secure bridge exposing limited IPC methods to renderer. |
| [`node-ui/renderer.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/renderer.js) | Renderer logic: UI event wiring, IPC calls, logging display. |
| [`node-ui/index.html`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/index.html) | HTML skeleton with navigation tabs and form placeholders. |
| [`node-ui/styles.css`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/styles.css) | Dark theme styling and responsive layout definitions. |
| [`node-ui/realm-data.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/realm-data.js) | Helper for populating item and pet search suggestions from static data. |
| [`node-ui/mega-alerts.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/mega-alerts.js) | Core alert engine loaded by main process for auction scanning. |
| [`package.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/package.json) | Declares Electron ≥18, build scripts, and `electron-builder` configuration. |
| `StaticData/` | JSON resources (item names, bonus IDs) bundled as extra resources. |

## Application Bootstrap and Lifecycle

The main process in [`node-ui/main.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/main.js) handles the complete application lifecycle from startup to shutdown.

### Version and Directory Initialization

On startup, the application reads `CURRENT_VERSION` from [`package.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/package.json) and establishes two critical paths:

- **Data Directory**: Determined by `getDataDir()`, storing user configurations like [`mega_data.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/mega_data.json), [`desired_items.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/desired_items.json), and [`ilvlList.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/ilvlList.json). The location varies between development and packaged builds, with optional custom paths saved in [`app-config.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/app-config.json).
- **Static Directory**: Accessed via `getStaticDir()`, containing bundled game data from the `StaticData/` folder.

### Window Creation and Security

The `createWindow()` function constructs a `BrowserWindow` with specific security constraints:

- Minimum dimensions and dark background with a fixed zoom factor of 80%
- [`preload.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/preload.js) injected as the preload script
- `nodeIntegration: false` and `contextIsolation: true` to prevent renderer access to Node APIs
- Navigation safeguards: external links open in the system browser via `setWindowOpenHandler` and `will-navigate` event listeners

### IPC Registration and State Management

The `setupIpc()` function registers numerous `ipcMain.handle` calls to expose safe APIs to the renderer. For example, loading the application state:

```javascript
ipcMain.handle("load-state", () => {
  ensureDataFiles()
  const rawMegaData = readJson(FILES.megaData, {})
  const normalizedMegaData = normalizeMegaData(rawMegaData)
  return {
    megaData: normalizedMegaData,
    desiredItems: readJson(FILES.desiredItems, {}),
    ilvlList: readJson(FILES.ilvlList, []),
    petIlvlList: readJson(FILES.petIlvlList, []),
    processRunning: Boolean(alertsProcess),
  }
})

```

These handlers cover file I/O, backup/restore operations, data directory changes, alert engine control, and UI zoom management.

### Alert Engine Integration

The main process manages the auction scanning functionality by loading [`node-ui/mega-alerts.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/mega-alerts.js) in-process. The `run-mega` IPC handler installs log and stop callbacks and tracks the `alertsProcess` flag to keep the UI responsive while background scans execute.

## Secure Communication Between Processes

Security in the Electron-based Node UI for AAA relies on strict process isolation with controlled communication channels.

The preload script acts as a security gatekeeper. By using `contextBridge.exposeInMainWorld`, it selectively exposes only required IPC methods:

```javascript
const { contextBridge, ipcRenderer } = require("electron")

contextBridge.exposeInMainWorld("electronAPI", {
  loadState: () => ipcRenderer.invoke("load-state"),
  saveMegaData: (payload) => ipcRenderer.invoke("save-mega-data", payload),
  startMega: () => ipcRenderer.invoke("run-mega"),
  stopMega: () => ipcRenderer.invoke("stop-mega"),
  // … additional whitelisted methods
})

```

This approach ensures that even if the renderer process executes untrusted code, it cannot access Node.js APIs or the file system directly. The renderer in [`node-ui/renderer.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/renderer.js) accesses these capabilities exclusively through `window.electronAPI`, maintaining a clear security boundary.

## Data Flow and Persistence

The Electron-based Node UI for AAA manages persistent data through JSON files in the user data directory and static assets bundled with the application.

### Configuration Files

User-specific configurations reside in the data directory established by `getDataDir()`:

- [`mega_data.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/mega_data.json) – Core scan configuration including realm selection and general settings
- [`desired_items.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/desired_items.json) – User-defined sniping rules for specific items
- [`desired_ilvl_list.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/desired_ilvl_list.json) – Item level based sniping criteria
- [`desired_pet_ilvl_list.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/desired_pet_ilvl_list.json) – Pet level sniping configuration

The UI provides backup functionality storing timestamped copies in `.../backup` with restore capabilities accessible through IPC handlers.

### Static Assets

Game data resources reside in the `StaticData/` directory and are bundled via Electron-Builder's `extraResources` configuration. These are accessed at runtime through `getStaticDir()` and include item tables, bonus IDs, and realm data used by [`node-ui/realm-data.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/realm-data.js) to populate search suggestions.

### Zoom Level Management

The UI stores the zoom factor in the main window's `webContents`. The renderer queries the current level via `get-zoom-level` and updates the display, while `set-zoom-level` changes the factor and persists it for the session, constrained between 50% and 200%.

## Build and Distribution

The Electron-based Node UI for AAA uses `electron-builder` for cross-platform packaging defined in [`package.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/package.json).

The build configuration produces:
- **Windows**: NSIS installer and portable executable (`x64` only)
- **macOS**: DMG and ZIP distributions (`x64` and `arm64` universal binaries)

Key build settings include:

```json
{
  "scripts": {
    "start": "electron .",
    "build": "electron-builder",
    "build:win": "electron-builder --win",
    "build:mac": "electron-builder --mac"
  },
  "build": {
    "appId": "com.azerothauctionassassin.app",
    "productName": "Azeroth Auction Assassin",
    "directories": { "output": "dist-electron" },
    "files": ["node-ui/**/*", "package.json"],
    "extraResources": [{ "from": "StaticData", "to": "StaticData", "filter": ["**/*"] }]
  }
}

```

The `extraResources` field ensures that `StaticData/` assets are available in production builds at the expected relative path.

## Security Considerations

The Electron-based Node UI for AAA implements several security best practices to protect user data and prevent code injection.

**Context Isolation and Preload Bridge**: By disabling `nodeIntegration` and enabling `contextIsolation`, the renderer cannot access Node.js APIs directly. The preload script in [`node-ui/preload.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/preload.js) exposes only whitelisted functions through `contextBridge`, creating a minimal attack surface.

**Credential Protection**: Sensitive fields including Discord webhooks, client IDs, secrets, and auction tokens are rendered as `<input type="password">` in the interface. These values are never hardcoded in source code and are persisted only in the user's local data directory, not in version control.

**Navigation Safeguards**: External links are forced to open in the system browser rather than within the Electron window. The `setWindowOpenHandler` and `will-navigate` event listeners in [`node-ui/main.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/main.js) prevent malicious navigation that could lead to phishing or remote code execution.

## Summary

- The Electron-based Node UI for AAA provides a cross-platform desktop interface using Electron ≥18 and Node.js, separating privileged operations (main process) from user interface code (renderer process).
- Security relies on `contextIsolation`, disabled `nodeIntegration`, and a preload bridge in [`node-ui/preload.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/preload.js) that exposes only necessary IPC methods via `window.electronAPI`.
- The main process in [`node-ui/main.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/main.js) manages window creation, data directory initialization, IPC registration for file I/O and alert engine control, and loads [`node-ui/mega-alerts.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/mega-alerts.js) for auction scanning.
- Data persistence uses JSON files ([`mega_data.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/mega_data.json), [`desired_items.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/desired_items.json), etc.) stored in a user-specific data directory, with backup/restore functionality and static assets bundled via `electron-builder`'s `extraResources`.
- The build system produces Windows (NSIS installer and portable) and macOS (DMG and ZIP) distributions, with the `StaticData/` folder included as extra resources for runtime access.

## Frequently Asked Questions

### What is the Electron-based Node UI for AAA?

The Electron-based Node UI for AAA is the desktop application interface for Azeroth Auction Assassin, built with Electron and Node.js. It provides a native windowed environment where users can configure auction sniping rules, manage item lists, and monitor scan results without using a command-line interface. The application runs as a multi-process Electron app with separate main and renderer processes communicating through secure IPC channels.

### How does the UI communicate between the main and renderer processes?

Communication occurs through Electron's `ipcMain` and `ipcRenderer` modules, bridged by the [`node-ui/preload.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/preload.js) script. The preload script uses `contextBridge.exposeInMainWorld` to expose specific methods like `loadState()`, `saveMegaData()`, and `startMega()` on the global `window.electronAPI` object. This allows the renderer process in [`node-ui/renderer.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/renderer.js) to invoke main process functions without direct access to Node.js APIs, maintaining security through context isolation.

### Where does the Electron-based Node UI store user configuration data?

User data is stored in JSON files within a dedicated data directory determined by the `getDataDir()` function in [`node-ui/main.js`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/node-ui/main.js). The specific files include [`mega_data.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/mega_data.json) for scan settings, [`desired_items.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/desired_items.json) for sniping rules, [`desired_ilvl_list.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/desired_ilvl_list.json) for item level criteria, and [`desired_pet_ilvl_list.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/desired_pet_ilvl_list.json) for pet configurations. The location varies between development and production builds, with optional custom paths saved in [`app-config.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/app-config.json), and backup copies stored in a `.../backup` subdirectory with timestamped filenames.

### How is the Electron-based Node UI packaged for distribution?

The application is packaged using `electron-builder` configured in [`package.json`](https://github.com/ff14-advanced-market-search/azerothauctionassassin/blob/main/package.json) to produce cross-platform binaries. For Windows, it generates both an NSIS installer and a portable executable for x64 architectures. For macOS, it creates DMG and ZIP distributions supporting both x64 and arm64 architectures. The build process includes the `node-ui/` directory contents and bundles the `StaticData/` folder as extra resources via the `extraResources` configuration, ensuring item tables and bonus IDs are available at runtime.