π₯οΈ Electron Desktop App
This guide covers building and running Libre WebUI as a native desktop application for macOS using Electron.
π― Overviewβ
The Electron desktop app provides:
- Native macOS experience - Proper window management, menu bar, traffic lights
- Offline-first design - Works with local Ollama without internet
- DMG installer - Easy drag-and-drop installation
- Auto-backend detection - Connects to existing backend or prompts to start one
π Prerequisitesβ
Before building the desktop app, ensure you have:
- Node.js 18+ installed
- npm or yarn package manager
- Xcode Command Line Tools (macOS):
xcode-select --install - Ollama installed and running (for AI functionality)
π Quick Startβ
Development Modeβ
Run the app in development mode with hot reloading:
# Start both frontend and Electron together
npm run electron:dev
This will:
- Start the Vite development server on port 5173
- Wait for the frontend to be ready
- Launch Electron pointing to the dev server
Production Buildβ
Build a distributable macOS app:
# Build frontend, backend, and create DMG
npm run electron:build
The built app will be available at:
- DMG:
dist-electron/Libre WebUI-{version}-mac-arm64.dmg - ZIP:
dist-electron/Libre WebUI-{version}-mac-arm64.zip
ποΈ Architectureβ
How It Worksβ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Electron App β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β βββββββββββββββββββ βββββββββββββββββββββββββββββββ β
β β Main Process β β Renderer Process β β
β β (Node.js) β β (React Frontend) β β
β β β β β β
β β β’ Window mgmt β β β’ UI rendering β β
β β β’ Menu bar β β β’ API calls to backend β β
β β β’ Backend checkβ β β’ WebSocket connection β β
β βββββββββββββββββββ βββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Communicates with β
β External Backend (port 3001) β
β β β
β Ollama (port 11434) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Key Filesβ
| File | Description |
|---|---|
electron/main.js | Main Electron process |
electron/preload.js | Preload script for security |
electron/splash.html | Splash screen during startup |
electron-builder.yml | Build configuration |
βοΈ Configurationβ
electron-builder.ymlβ
The build configuration supports:
appId: com.librewebui.app
productName: Libre WebUI
mac:
category: public.app-category.productivity
target:
- target: dmg
arch:
- arm64 # Apple Silicon
- target: zip
arch:
- arm64
darkModeSupport: true
hardenedRuntime: true
Available Scriptsβ
| Script | Description |
|---|---|
npm run electron:dev | Development mode with hot reload |
npm run electron:build | Build production DMG for macOS |
npm run electron:pack | Build without creating installer |
π¨ macOS Integrationβ
Title Barβ
The app uses a custom title bar style (hiddenInset) for a native macOS look:
- Traffic light buttons integrated into the sidebar
- Extra padding added to avoid overlap with controls
- Draggable title bar area for window movement
Window Featuresβ
- Minimum size: 800x600 pixels
- Default size: 1400x900 pixels
- Dark mode support: Follows system preference
- Traffic light position: Custom positioned at (15, 15)
Menu Barβ
Full native menu bar with:
- App menu (About, Preferences, Quit)
- Edit menu (Undo, Redo, Cut, Copy, Paste)
- View menu (Reload, DevTools, Zoom)
- Window menu (Minimize, Zoom, Full Screen)
- Help menu (Documentation, GitHub, Report Issue)
π§ Troubleshootingβ
Common Issuesβ
1. App shows "Connecting to backend..." forever
The backend needs to be running separately. Start it with:
npm run dev:backend
Or run the full development environment:
npm run dev
2. Click events not working in sidebar
This was fixed by adding -webkit-app-region: no-drag to interactive elements. If you experience this, ensure you have the latest version.
3. Logo/icons not displaying
Assets need relative paths for file:// protocol. Use ./logo.png instead of /logo.png.
4. Navigation doesn't work after clicking
The app uses HashRouter instead of BrowserRouter for file:// protocol compatibility. This is handled automatically.
Build Errorsβ
SQLite/SQLCipher compilation errors:
# Clear npm cache and rebuild
rm -rf node_modules
npm install
npm run electron:build
Code signing warnings:
skipped macOS application code signing
This is normal for development builds. For distribution, you'll need an Apple Developer certificate.
π¦ Distributionβ
Creating a Signed Buildβ
For App Store or notarized distribution:
- Get an Apple Developer account
- Create signing certificates in Xcode
- Create entitlements file at
electron/entitlements.mac.plist - Configure signing in
electron-builder.yml:mac:
hardenedRuntime: true
gatekeeperAssess: false
entitlements: electron/entitlements.mac.plist
entitlementsInherit: electron/entitlements.mac.plist
GitHub Releasesβ
The build configuration includes GitHub release support:
publish:
provider: github
owner: libre-webui
repo: libre-webui
To publish a release:
# Build and publish
npm run electron:build -- --publish always
π Securityβ
Context Isolationβ
The app uses proper security practices:
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
webSecurity: true,
preload: path.join(__dirname, 'preload.js'),
}
External Linksβ
External links are opened in the default browser, not inside the app:
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
shell.openExternal(url);
return { action: 'deny' };
});
π§ Limitationsβ
Current Limitationsβ
- macOS only - Currently only Apple Silicon (arm64) is supported
- Requires external backend - The backend must run separately
- No auto-updates - Updates require downloading new DMG
Future Plansβ
- Windows and Linux support
- Bundled backend option
- Auto-update functionality
- Universal binary (arm64 + x64)
π Technical Detailsβ
Bundle Contentsβ
The built app includes:
- Electron framework (~200MB)
- Built frontend (~2MB)
- Plugin configurations (~50KB)
- Assets and icons
Performanceβ
- Startup time: ~2-3 seconds
- Memory usage: ~150-300MB (depends on chat history)
- Disk space: ~250MB installed
π Ready to build? Run npm run electron:build and find your DMG in dist-electron/.