Architecture

1 minute read

Overview

HyPrism follows a Console + IPC + React SPA architecture.

At a high level, a .NET backend hosts the application logic, Electron provides the desktop shell, and a React SPA renders the UI. Communication between layers is done through typed IPC channels.

.NET Console Backend
────────────────────────────────
Program.cs
├─ Bootstrapper.cs   (DI container)
├─ Services/         (business logic)
└─ IpcService.cs     (IPC registry)

⇅ Electron.NET socket bridge

Electron Main Process
────────────────────────────────
BrowserWindow (frameless)
└─ preload.js        (contextBridge)
   ⇅ ipcRenderer

React SPA
────────────────────────────────
App.tsx              (routing)
pages/               (views)
components/          (shared UI)
lib/ipc.ts           (generated bindings)

Startup Flow

  1. Program.Main() initializes the logger
  2. ElectronLogInterceptor is attached to stdout/stderr
  3. Bootstrapper.Initialize() builds the DI container
  4. Electron is started via ElectronNetRuntime
  5. A frameless BrowserWindow loads index.html
  6. IpcService.RegisterAll() registers IPC handlers
  7. React mounts and begins IPC-based data access

Communication Model

All frontend ↔ backend communication uses named IPC channels.

hyprism:{domain}:{action}

Examples:
hyprism:game:launch
hyprism:settings:get
hyprism:i18n:set

Channel Types

TypeDirectionDescription
sendReact → .NETFire-and-forget
invokeReact → .NET → ReactRequest / reply
event.NET → ReactPush updates

Security Model


Dependency Injection

All services are registered as singletons in Bootstrapper.cs:

var services = new ServiceCollection();

services.AddSingleton<ConfigService>();
services.AddSingleton<IpcService>();
// ...

return services.BuildServiceProvider();

IpcService acts as the central bridge and receives dependencies via constructor injection.


Log Interception

Electron.NET writes unstructured output to stdout/stderr. HyPrism intercepts this using a custom ElectronLogInterceptor.

Behavior: