Process separation
Modules divide execution between the Electron Main process and the Renderer process to ensure backend reliability and interface responsiveness:Main process
The main process coordinates the installation, update checks, uninstallation, and execution of backing terminal commands (such as executing Python scripts or starting a local model binary vianode-pty).
-
Entrypoint:
src/main.ts(compiled and bundled toscripts/main.mjsas an ES module). - Responsibility: Exposes backend lifecycle hooks and commands for execution.
-
Signature:
Renderer process
The renderer process handles card visualization, settings/argument configuration forms, and installation wizard steppers.-
Entrypoint:
src/renderer.ts(compiled and bundled toscripts/renderer.mjsas an ES module). - Responsibility: Registers card UI layouts, defines category mappings, and specifies custom argument inputs.
-
Signature:
Boot and loading sequence
LynxHub performs the following steps to load modules during application startup:1. Discovery and validation
During startup, the host scans folders inside thePlugins/ directory. It ensures that required files exist before loading a module.
2. Import and aggregation
The host imports the backend entrypointscripts/main.mjs. It calls initialModule and registers card-specific backend operations. The frontend then dynamically loads scripts/renderer.mjs using the custom protocol to display card components.
Custom plugin protocol (lynxplugin://)
Modern browsers and Chromium engines prevent loading assets or scripts directly from the local file system (file:// URLs) due to security restrictions.
To resolve this safely, LynxHub registers a custom protocol handler at boot:
- Protocol:
lynxplugin:// - Hostname mapping: The hostname corresponds to the plugin folder ID.
- Path mapping: The path maps directly to files under
<AppData>/Plugins/<id>/<path>.
Host card state management
When card modules run, the host application manages their states internally. Module developers do not need to write state management code. The host aggregates card states using its internal stores:Host Zustand store (local)
The host maintains a Zustand store for each mounted card instance to handle interface updates:- Tracking selected arguments.
- Monitoring installation and compiler progress.
- Streaming active terminal outputs.
- Displaying loading states.
Host Redux store (global)
The host updates its central Redux store when cards launch or close, allowing navigation bars and panels to track active processes.Rollup build configuration
To compile and package your module correctly, configure Rollup to output ES modules. Below is the standard Rollup configuration (rollup.config.mjs) used by the module template:
electron) in your build config for the main script so they are not bundled.
Development vs. production environments
LynxHub provides two separate loading strategies to optimize the developer experience:Development mode
During development, the host redirects module loading to local aliases to support instant code updates:- Renderer:
@lynx_module/renderer(pointing to/module/src/renderer) - Main:
module/src/main
Production mode
In production:- Validation: LynxHub scans folders inside the
Pluginsdirectory. It ensures thatscripts/main.mjsandscripts/renderer.mjsexist before loading. - Filtering: Disabled cards (
plugin.disabledCards) are filtered out early in both processes so they are never loaded into memory.