Skip to main content

Desktop Clients

LA Router is designed to run alongside desktop applications — embedded directly into Electron or Tauri apps for Mac, Windows, and Linux. This gives desktop users the full power of local AI without any cloud dependency.

Architecture

In a desktop deployment, LA Router runs as a local sidecar process on the same machine as the desktop app. The Electron or Tauri client communicates with LA Router over localhost, and LA Router manages the local model lifecycle automatically.

Electron Integration

For Electron-based desktop apps, LA Router runs as a child process spawned by the main process:

// main.ts (Electron main process)
import { spawn } from 'child_process';
import path from 'path';

let routerProcess: ChildProcess;

app.on('ready', () => {
// Start LA Router as a sidecar
routerProcess = spawn(
path.join(process.resourcesPath, 'larouter'),
['serve', '--port', '18790'],
{ env: { ...process.env, LAROUTER_DATA: app.getPath('userData') } }
);

routerProcess.stdout?.on('data', (data) => {
console.log(`[LARouter] ${data}`);
});
});

app.on('quit', () => {
routerProcess?.kill();
});

The renderer process then calls LA Router like any OpenAI client:

// renderer (React component)
const response = await fetch('http://localhost:18790/v1/chat/completions', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'auto',
messages: [{ role: 'user', content: userInput }],
}),
});

Tauri Integration

For Tauri apps (Rust-based, smaller footprint), LA Router integrates via a Tauri sidecar:

# tauri.conf.json — register LA Router as a sidecar
{
"bundle": {
"externalBin": ["binaries/larouter"]
}
}
// src-tauri/src/main.rs
use tauri::api::process::Command;

fn main() {
tauri::Builder::default()
.setup(|app| {
// Spawn LA Router sidecar
let (mut rx, _child) = Command::new_sidecar("larouter")
.expect("failed to find larouter sidecar")
.args(["serve", "--port", "18790"])
.spawn()
.expect("failed to spawn larouter");

// Log output
tauri::async_runtime::spawn(async move {
while let Some(event) = rx.recv().await {
println!("[LARouter] {:?}", event);
}
});

Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

The frontend code is identical — call http://localhost:18790 from the React webview.

Platform-Specific Notes

PlatformModel FormatGPU SupportNotes
macOS (Apple Silicon)MLX preferred, GGUF supportedMetal GPU accelerationBest local AI experience — unified memory, fast inference
macOS (Intel)GGUF onlyCPU onlyUse smaller models (2B–4B) for acceptable speed
WindowsGGUF onlyCUDA, VulkanNVIDIA GPUs recommended for 26B+ models
LinuxGGUF onlyCUDA, ROCm, VulkanFull GPU stack support

Model Storage

When running as a desktop sidecar, LA Router stores downloaded models in the application's data directory:

PlatformDefault Path
macOS~/Library/Application Support/LARouter/models/
Windows%APPDATA%/LARouter/models/
Linux~/.local/share/LARouter/models/

Offline Operation

A key advantage of the desktop deployment is fully offline operation:

  1. Download models once while connected to the internet
  2. LA Router serves them locally via llama.cpp
  3. All Heartbeat, Simple, and Moderate tasks work without any network connection
  4. Complex/Frontier tasks queue until connectivity is restored (or can be disabled)
Best Practice

For desktop deployments, pre-download at least the 4B model during app setup. This ensures users have a capable local model for the majority of tasks without requiring ongoing internet access.

Security Benefits

Running LA Router locally on the desktop provides:

  • Zero data exfiltration — all inference happens on the user's machine
  • No API keys required — local models don't need authentication
  • No network exposure — LA Router binds to localhost only
  • User-controlled — the user decides which models to download and when to use cloud fallback