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:

  1. Electron main process – Handles the tray icon, native window management, and boots the Express server. This logic resides in desktop/src/main.ts.
  2. 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.
  3. 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 the FREEAPI_REPO environment 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 nvm or fnm).
  • 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 infoRun 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) or npm run desktop:dist:win (Windows), which compiles the native better-sqlite3 addon and packages everything via desktop/electron-builder.yml.
  • For development, run npm run rebuild:native followed by npm run dev inside the desktop/ directory to enable hot-reloading.
  • Data persists in platform-specific application-support folders (~/Library/Application Support/FreeLLMAPI/ or %APPDATA%\FreeLLMAPI\), with the server binding to 127.0.0.1:31415 by 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →