How to Migrate from LiteLLM or OpenRouter to OmniRoute: A Complete Guide
Migrate from LiteLLM or OpenRouter to OmniRoute by deploying the self-hosted binary, registering your existing API keys, and updating your client base URL to http://localhost:20128/v1/ while optionally adopting auto-combo routing syntax.
OmniRoute is a self-hosted, all-in-one LLM routing layer that replaces both the SDK-style approach of LiteLLM and the hosted SaaS gateway of OpenRouter. This guide walks you through the exact migration steps based on the source code in diegosouzapw/OmniRoute, with specific references to configuration files, provider registries, and the auto-combo routing engine.
Understanding the Migration Path
Moving from LiteLLM or OpenRouter to OmniRoute involves three core steps. Each step maps directly to architectural components in the OmniRoute codebase.
Step 1: Deploy OmniRoute and Initialize the SQLite Data Store
OmniRoute stores every provider credential, model catalog, combo definition, and rate-limit state in a single, version-controlled SQLite database. This differs fundamentally from LiteLLM's in-process caching, which loses state on restart.
The default data directory is ~/.omniroute/. Database initialization and migrations are handled in src/lib/db/core.ts. According to the database guide in docs/ops/DATABASE_GUIDE.md (lines 9-20), the SQLite backend ensures persistence for connection cooldowns, circuit-breaker status, quota tracking, and model-level lockouts.
# Install OmniRoute globally
npm install -g omniroute
# Start the server on default port 20128
omniroute serve
Step 2: Register Your Existing API Keys
OmniRoute's provider registry in open-sse/config/providerRegistry.ts automatically syncs the live model catalog for each provider you add. This includes native support for OpenRouter as a provider itself.
Register your existing keys via the CLI:
# Add an OpenRouter connection
omniroute providers add openrouter --api-key sk-your-openrouter-key
# Add a direct OpenAI connection (if you had one in LiteLLM)
omniroute providers add openai --api-key sk-your-openai-key
# Verify all registered providers and their synced models
omniroute providers list
The OpenRouter entry is documented in docs/reference/PROVIDER_REFERENCE.md at line 279. The DefaultExecutor in open-sse/executors/DefaultExecutor.ts handles all provider types uniformly—adding or removing a provider only touches the registry, requiring no per-client code changes.
Step 3: Point Client Code at the OmniRoute HTTP API
Update your application to call OmniRoute's OpenAI-compatible endpoint at http://127.0.0.1:20128/v1/. The main chat completions route is implemented in src/app/api/v1/chat/completions/route.ts.
Before (LiteLLM Python):
import openai
client = openai.OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key="sk-your-openrouter-key"
)
response = client.chat.completions.create(
model="openrouter/anthropic/claude-3.5-sonnet:free",
messages=[{"role": "user", "content": "Explain the migration steps"}],
temperature=0.2
)
After (OmniRoute):
curl -X POST http://127.0.0.1:20128/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-your-omniroute-key" \
-d '{
"model": "auto/coding:free",
"messages": [{"role":"user","content":"Explain the migration steps"}],
"temperature": 0.2
}'
You can also preserve existing OpenRouter model strings while gaining OmniRoute's resilience features:
curl -X POST http://127.0.0.1:20128/v1/chat/completions \
-H "Authorization: Bearer $(omniroute auth export --json | jq -r .apiKey)" \
-H "Content-Type: application/json" \
-d '{
"model": "openrouter/anthropic/claude-3.5-sonnet:free",
"messages": [{"role":"user","content":"What’s new in v3.8.50?"}]
}'
Key Architectural Differences That Simplify Migration
Unified Provider Layer
All providers—OpenAI, Anthropic, OpenRouter, and others—are represented by a single DefaultExecutor in open-sse/executors/DefaultExecutor.ts. This abstraction means you can switch between direct provider access and aggregated access without changing client code.
SQLite-Backed State Persistence
Unlike LiteLLM's in-process caching, OmniRoute persists all state to SQLite. The core database implementation in src/lib/db/core.ts handles migrations and automatic backup. Server restarts preserve rate-limit information, circuit-breaker status, and quota tracking that would otherwise be lost.
Auto-Combo Routing with OpenRouter-Style Suffixes
The auto-combo engine in open-sse/services/autoCombo/suffixComposition.ts interprets auto/<category>:<tier> suffixes. This syntax, inspired by OpenRouter, lets you request capabilities rather than specific models:
auto/coding:fast— Best coding model optimized for speedauto/vision:pro— Top-tier vision-capable modelauto/reasoning:cheap— Most cost-effective reasoning model
As documented in docs/routing/AUTO-COMBO.md (lines 31-33), the engine scores available models against your requested capability and tier, then selects the optimal provider.
Zero-Migration Credential Support
Public upstream OAuth credentials (like Google client IDs) are automatically resolved via resolvePublicCred() in open-sse/utils/publicCreds.ts. Environment variables stored in .env for LiteLLM or OpenRouter continue to work without modification.
Robust Quota and Error Handling
OpenRouter-specific quota counters and 402 rate-limit handling are integrated into OmniRoute's quota-share subsystem in open-sse/services/quotaShare.ts. Instead of abrupt failures, you get graceful cooldowns with persistent tracking. See docs/routing/QUOTA_SHARE.md (line 33) for implementation details.
When to Migrate: OmniRoute vs. LiteLLM vs. OpenRouter
The comparison table in docs/comparison/OMNIROUTE_VS_ALTERNATIVES.md (lines 14-20) clarifies the trade-offs:
| Aspect | OmniRoute | LiteLLM | OpenRouter (SaaS) |
|---|---|---|---|
| Deployment | Self-hosted | Python library/with hosted proxy | Fully hosted |
| State persistence | SQLite-backed | In-process only | Cloud-managed |
| Rate limit control | Full visibility and customization | Limited | Opaque |
| Routing policies | Custom combo strategies | Basic fallback | Provider-defined |
| Circuit breakers | Built-in | Manual implementation | None |
Choose OmniRoute when you need self-hosted reliability, auditability, custom routing strategies, or persistent quota tracking that survives restarts.
Essential Migration Files
| File | Purpose in Migration |
|---|---|
docs/comparison/OMNIROUTE_VS_ALTERNATIVES.md |
Feature comparison for decision-making |
src/app/api/v1/chat/completions/route.ts |
OpenAI-compatible endpoint you call instead of OpenRouter |
open-sse/config/providerRegistry.ts |
Where you add or edit provider connections |
src/lib/db/core.ts |
SQLite bootstrap, migrations, and backup |
open-sse/services/autoCombo/suffixComposition.ts |
Parsing logic for auto/<category>:<tier> suffixes |
docs/reference/ENVIRONMENT.md |
Environment variables for data directory and encryption |
Complete Migration Checklist
- Install and start:
npm install -g omniroute→omniroute serve - Import keys:
omniroute providers add <provider> --api-key <key>for each existing credential - Verify catalog:
omniroute providers listto confirm model sync - Update endpoints: Change base URL to
http://<host>:20128/v1/in all clients - Optional: Adopt auto-combos: Replace hard-coded model IDs with
auto/<category>:<tier>syntax - Validate deployment: Run
omniroute healthandomniroute providers test-all
Summary
- OmniRoute replaces both LiteLLM and OpenRouter with a self-hosted, SQLite-backed routing layer
- Three-step migration: deploy binary, register existing keys, update endpoint URL
- Keep existing model strings or adopt
auto/<category>:<tier>combos for intelligent routing - Gain persistent state, circuit breakers, and quota tracking that LiteLLM lacks
- Zero credential changes required—existing
.envvariables work viapublicCreds.tsresolution
Frequently Asked Questions
Can I use OpenRouter as a provider within OmniRoute?
Yes. Register OpenRouter as one of many providers using omniroute providers add openrouter --api-key <key>. The provider registry in open-sse/config/providerRegistry.ts automatically syncs OpenRouter's live model catalog. You can then route to OpenRouter models directly or through OmniRoute's auto-combo engine.
Do I need to change my existing model identifiers?
No. OmniRoute's suffixComposition.ts parser accepts OpenRouter-style model strings like openrouter/anthropic/claude-3.5-sonnet:free without modification. However, adopting auto/<category>:<tier> syntax unlocks OmniRoute's capability-based routing and failover features.
How does OmniRoute handle rate limits compared to LiteLLM?
LiteLLM caches rate-limit state in-memory and loses it on process restart. OmniRoute persists all quota counters, circuit-breaker states, and cooldown timers to SQLite via src/lib/db/core.ts. The quota-share subsystem in open-sse/services/quotaShare.ts also implements graceful degradation with 402 handling that LiteLLM does not provide natively.
What happens to my LiteLLM configuration files?
LiteLLM YAML configurations are not automatically imported. You must recreate provider entries using omniroute providers add. However, environment variables referenced in LiteLLM configs (API keys, base URLs) typically require no changes due to OmniRoute's automatic public credential resolution in open-sse/utils/publicCreds.ts.
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 →