How to Set Up the FreeLLMAPI Desktop App: Complete Build Guide
TLDR: FreeLLMAPI provides a native Electron menu-bar application that bundles the Express router and React dashboard, enabling you to run a local OpenAI-compatible API endpoint on 127.0.0.1:31415 by building from the desktop/ directory using Node.js and standard C++ toolchains.
The FreeLLMAPI desktop application is a self-contained, native menu-bar app that runs the full inference router locally alongside a React-based dashboard. Located in the desktop/ directory of the tashfeenahmed/freellmapi repository, this Electron-based package compiles directly from the same monorepo source that powers the Docker image and web UI. This guide covers the architecture, build prerequisites, and step-by-step commands required to compile and launch the app on macOS and Windows.
Architecture Overview
The desktop app bundles three core components into a single native experience:
- Electron main process – Handles the tray icon, native window management, and boots the Express server. This logic resides in
desktop/src/main.ts. - Renderer process – A glass-styled HTML pop-over (
desktop/renderer/popover.html) that displays live request statistics and a copy-button for the unified API key. - Shared server code – The identical OpenAI-compatible router used by the Docker image, located at
server/src/services/router.ts. The desktop build imports this via theFREEAPI_REPOenvironment variable.
Data persistence uses SQLite (better-sqlite3) compiled against Electron’s ABI. Keys and analytics are stored in platform-specific application-support folders, while the npm run rebuild:native script in desktop/package.json automates the native addon compilation.
Prerequisites
Before building, ensure your system has the required native compilation tools:
- macOS: Xcode Command Line Tools (
xcode-select --install). - Windows: Visual Studio Build Tools with the Desktop development with C++ workload.
- Both: Node.js 20+ (recommended to use
nvmorfnm). - Optional: Docker is only required if you prefer a pre-built binary installer; it is not needed for local compilation.
The build process must compile the better-sqlite3 native module against Electron’s specific ABI version, which the provided npm scripts handle automatically.
Building the Desktop App
From the repository root (the folder containing the monorepo package.json), execute the following commands:
# Install dependencies for all workspace packages (server, client, desktop)
npm install
# Build the macOS installer (.dmg)
npm run desktop:dist
# Build the Windows installer (.exe)
npm run desktop:dist:win
These commands trigger the Electron Builder configuration defined in desktop/electron-builder.yml. The process compiles the React UI, bundles the Express router, compiles native dependencies, and outputs a signed (or unsigned) installer to desktop/dist-electron/.
Note: Locally built installers are unsigned. On macOS, you may need to right-click and select Open to bypass Gatekeeper; on Windows, click More info → Run anyway in the SmartScreen dialog.
Running the App in Development Mode
For iterative development without packaging, use the development workflow:
cd desktop
npm install
npm run rebuild:native # Compile better-sqlite3 for Electron's ABI
npm run dev # Launches the Electron app with hot-reload
Set the FREEAPI_REPO environment variable to point to a different server checkout if needed. Alternatively, run npm run desktop:dev from the repository root to build the client assets first (npm run build -w client) and then launch the desktop dev server in one step.
Data Storage and Configuration
The desktop server binds exclusively to 127.0.0.1:31415 by default, ensuring isolation from the network unless explicitly exposed. Persistent data is stored in the following locations:
- macOS:
~/Library/Application Support/FreeLLMAPI/ - Windows:
%APPDATA%\FreeLLMAPI\
These directories contain the SQLite database, encrypted provider API keys, request analytics, and the auto-generated ENCRYPTION_KEY file. You can customize the listening port by editing desktop/src/config.ts or setting the PORT environment variable before launch.
Using the Unified API Key
Once the menu-bar icon is active, click it and select Open Dashboard to access the full React UI. Add your free-tier provider credentials in the Keys section; these are encrypted and stored locally. Copy the unified freellmapi-… key from the header to use with any OpenAI-compatible client:
from openai import OpenAI
client = OpenAI(
base_url="http://127.0.0.1:31415/v1",
api_key="freellmapi-your-unified-key",
)
response = client.chat.completions.create(
model="auto",
messages=[{"role": "user", "content": "Explain quantum computing"}],
)
print(response.choices[0].message.content)
Summary
- The FreeLLMAPI desktop app is an Electron-based menu-bar application that bundles the Express router (
server/src/services/router.ts) and React dashboard into a single native binary. - Build the installer from the repository root using
npm run desktop:dist(macOS) ornpm run desktop:dist:win(Windows), which compiles the nativebetter-sqlite3addon and packages everything viadesktop/electron-builder.yml. - For development, run
npm run rebuild:nativefollowed bynpm run devinside thedesktop/directory to enable hot-reloading. - Data persists in platform-specific application-support folders (
~/Library/Application Support/FreeLLMAPI/or%APPDATA%\FreeLLMAPI\), with the server binding to127.0.0.1:31415by default.
Frequently Asked Questions
Do I need Docker to run the desktop app?
No. Docker is only required if you want to use a pre-built binary installer from the releases page. Building locally requires only Node.js and a C/C++ toolchain (Xcode CLT on macOS or Visual Studio Build Tools on Windows) to compile the native better-sqlite3 dependency.
Where is the encryption key stored?
The app generates an ENCRYPTION_KEY on first launch and saves it alongside the SQLite database in the platform-specific application-support folder (~/Library/Application Support/FreeLLMAPI/ on macOS or %APPDATA%\FreeLLMAPI\ on Windows). You can also set this key manually via environment variables before starting the app.
Can I change the listening port from 31415?
Yes. The desktop server binds to 127.0.0.1:31415 by default. To use a different port, either edit desktop/src/config.ts or set the PORT environment variable before launching the application (e.g., PORT=8080 npm run dev).
Is the desktop version compatible with the web dashboard?
Yes. Both interfaces use the identical server code and share the same SQLite store. Any changes made in the desktop dashboard—such as adding provider keys or reordering the fallback chain—are immediately reflected in the web UI if you run it, and vice versa, because they both read from the same local database.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →