Frontend
Electron
Desktop wrapper, IPC, and security model
Main Process
Entry Point (electron/main.ts)
The main process creates the browser window and manages the application lifecycle.
- Dev mode (
!app.isPackaged): loadshttp://localhost:3000 - Production: loads
out/index.html(static export) - Hidden title bar with traffic light positioning for macOS
Dev Detection
const isDev =
process.env.NODE_ENV !== "production" &&
!app.isPackaged;Using !app.isPackaged is more reliable than checking NODE_ENV, which may not be set in all dev environments.
Preload Script
Exposed API (electron/preload.ts)
Exposes a secure API via contextBridge:
// In renderer (React), access via:
window.exfilguardian.capture.start()
window.exfilguardian.capture.stop()
window.exfilguardian.capture.getStatus()
window.exfilguardian.threats.list()
window.exfilguardian.threats.get(id)
window.exfilguardian.metrics.get()
window.exfilguardian.app.getVersion()IPC Handlers
Flow (electron/ipc/index.ts)
IPC handlers bridge the Electron main process with the Rust API:
## Security Model
### Settings
| Setting | Value | Why |
|---------|-------|-----|
| `contextIsolation` | `true` | Renderer has no Node.js access |
| `nodeIntegration` | `false` | No `require()` in renderer |
| `sandbox` | `true` | Restricts renderer capabilities |
### Principle
All data passes through `contextBridge` only. The renderer never directly contacts the Rust API or accesses the filesystem.
## Bun Compatibility
### Trusted Dependencies
Bun blocks postinstall scripts by default. Electron needs its binary installed via postinstall, so `package.json` must include:
```json
{
"trustedDependencies": ["electron"]
}Production Build
Static Export
For Electron distribution, enable static export in next.config.ts:
const nextConfig: NextConfig = {
output: "export",
images: { unoptimized: true },
};Platform Formats
Then bun run dist packages everything into a native app via electron-builder.
| Platform | Format |
|---|---|
| macOS | .dmg |
| Windows | .nsis (installer) |
| Linux | .AppImage |