OmniRoute Project Structure: A Deep Dive into the Next.js, Electron, and Streaming Engine Architecture
OmniRoute organizes its codebase as a monorepo with distinct top-level directories for the Next.js 16 frontend (src/), a dedicated streaming engine (open-sse/), an Electron desktop wrapper (electron/), and comprehensive test suites (tests/).
The repository at diegosouzapw/OmniRoute separates concerns between UI rendering, API routing, and server-side streaming while maintaining tight integration through type-safe TypeScript utilities. This architecture supports everything from chat completion endpoints to complex multi-provider routing strategies.
Top-Level Directory Layout
The project structure follows a clear separation of concerns at the root level:
| Directory | Purpose | Key Contents |
|---|---|---|
src/ |
Core TypeScript application code | Next.js App Router, API routes, domain libraries |
open-sse/ |
Server-side streaming engine | Request handlers, provider executors, translators |
electron/ |
Desktop application wrapper | Main process, preload scripts, OAuth management |
tests/ |
Verification suites | Unit tests (Vitest), integration tests, E2E (Playwright) |
docs/ |
Documentation and specifications | OpenAPI specs, architecture diagrams |
config/ |
Runtime configuration | i18n settings, quality baselines, payload rules |
public/ |
Static assets | Icons, service workers, public files |
Root configuration files include package.json, tsconfig.json, and next.config.mjs, which define the build pipeline and TypeScript compilation settings for the entire monorepo.
The Next.js Application Layer
App Router and API Endpoints
The src/app/ directory houses the Next.js 16 App Router implementation. This contains page components, layouts, and error boundaries that render the dashboard and API Explorer.
API routes reside under src/app/api/v1/, following a RESTful structure:
src/app/api/v1/chat/completions/route.ts– Primary endpoint for streaming chat completionssrc/app/api/v1/models/route.ts– Provider model listing and metadatasrc/app/api/v1/_shared/rateLimit.ts– Shared rate-limiting logic across routes
Each route validates input using Zod schemas from src/shared/validation/ before delegating to the streaming engine.
Domain Libraries and Shared Utilities
The src/lib/ directory contains domain-specific modules isolated by concern:
src/lib/db/core.ts– SQLite connection singleton and schema definitionssrc/lib/skills/registry.ts– A2A protocol skill registrationsrc/lib/guardrails/– Safety and content filtering implementations
Shared utilities in src/shared/ provide cross-cutting functionality:
src/shared/validation/providerSchema.ts– Zod schemas for provider identifierssrc/shared/utils/tiktokenCounter.ts– Token counting utilitiessrc/shared/utils/apiKey.ts– API key policy enforcement
Frontend State Management
The src/store/ directory contains Zustand stores for UI state:
src/store/themeStore.ts– Theme preferences and dark mode toggling- Notification management and email privacy settings
The Streaming Engine (open-sse/)
The open-sse/ directory is the heart of OmniRoute's request processing pipeline. This is where Server-Sent Events (SSE) are orchestrated between upstream LLM providers and downstream clients.
Request Handlers and Executors
Incoming requests flow through specialized handlers:
open-sse/handlers/chatCore.ts– Entry point for chat completion requestsopen-sse/handlers/responsesHandler.ts– Response transformation logicopen-sse/handlers/embeddings.ts– Vector embedding requests
Executors in open-sse/executors/ handle provider-specific HTTP implementations:
open-sse/executors/default.ts– Base executor for OpenAI-compatible APIsopen-sse/executors/cursor.ts– Cursor-specific request formattingopen-sse/executors/vertex.ts– Google Vertex AI integration
Translation and Routing Services
The open-sse/translator/ directory converts between OpenAI-compatible request formats and provider-specific payloads. Supporting services include:
open-sse/services/combo.ts– Combo routing engine for multi-provider strategies (sequential, parallel, weighted)open-sse/services/rateLimitManager.ts– Distributed rate limitingopen-sse/utils/– Size estimation, error handling, and keep-alive management
Desktop and Testing Infrastructure
Electron Wrapper
The electron/ directory wraps the Next.js application as a native desktop client:
electron/main.js– Creates the browser window and sets up IPC channelselectron/preload.js– Securely exposes APIs to the renderer processelectron/loginManager.js– Handles OAuth flows for desktop authentication
The Electron wrapper reuses the same Next.js build output, allowing the full OmniRoute UI to run outside the browser.
Test Organization
The tests/ directory is organized by scope:
tests/unit/– Fast module tests for provider registries and guardrailstests/integration/– Full request pipeline testingtests/e2e/– Playwright browser automation tests
Tests run with the native Node test runner (node --import tsx/esm --test) and Vitest for the MCP server components.
How Request Flow Works Through the Project Structure
Understanding the project structure requires tracing how a chat completion request travels through the system:
- Client requests
/api/v1/chat/completionsvia the Next.js UI insrc/app/ - Route validation occurs in
src/app/api/v1/chat/completions/route.tsusing Zod schemas - Authentication is enforced via
src/shared/utils/apiKey.ts - Delegation to
src/sse/handlers/chat.tsbridges the HTTP API to the streaming engine - Translation in
open-sse/translator/converts the request format for the target provider - Execution via
open-sse/executors/dispatches to the upstream LLM (OpenAI, Anthropic, etc.) - Streaming responses flow back through
open-sse/handlers/chatCore.tsto the client
The combo routing engine (open-sse/services/combo.ts) can intercept this flow to run multiple providers in parallel or sequence, applying cost-optimization or fallback strategies.
Extending the Architecture
Adding a New API Route
Create a new route file under src/app/api/v1/:
// src/app/api/v1/custom/hello/route.ts
import { json } from 'next/headers';
import { ensureApiKey } from '@/shared/utils/apiKey';
export async function GET() {
await ensureApiKey(); // enforce API-key policy
return json({ message: 'Hello from OmniRoute!' });
}
Registering a Custom Executor
Implement a new provider by extending the default executor:
// open-sse/executors/myProvider.ts
import { DefaultExecutor } from './default';
export class MyProviderExecutor extends DefaultExecutor {
protected buildUrl() {
return 'https://api.myprovider.com/v1/chat/completions';
}
protected buildHeaders() {
return {
Authorization: `Bearer ${this.credentials.apiKey}`,
'Content-Type': 'application/json',
};
}
}
Then register it in the factory:
// open-sse/executors/index.ts
import { MyProviderExecutor } from './myProvider';
export function getExecutor(providerId: string) {
if (providerId === 'myProvider') return new MyProviderExecutor();
// …existing branches…
}
Integrating with Electron IPC
Expose functionality to the renderer via the preload script:
// electron/preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('omni', {
getVersion: () => ipcRenderer.invoke('get-version'),
});
Access from the frontend:
// src/app/dashboard/page.tsx
useEffect(() => {
window.omni.getVersion().then(v => setVersion(v));
}, []);
Summary
- OmniRoute uses a monorepo project structure separating the Next.js frontend (
src/), streaming engine (open-sse/), and Electron desktop client (electron/) - The
src/app/api/v1/directory contains REST endpoints that validate requests before delegating toopen-ssehandlers - Streaming logic is isolated in
open-sse/with clear boundaries between handlers, translators, and provider-specific executors - Type safety is enforced through Zod schemas in
src/shared/validation/and used consistently across API routes - The combo routing engine (
open-sse/services/combo.ts) enables sophisticated multi-provider strategies without mixing concerns into the API layer - Electron reuses the Next.js build output, maintaining a single codebase for web and desktop
Frequently Asked Questions
What is the relationship between src/app/api and the open-sse directory?
The src/app/api/v1/ routes handle HTTP ingress, authentication, and input validation using Zod schemas. Once validated, these routes delegate to thin wrappers in src/sse/handlers/, which bridge to the open-sse/ streaming engine. This separation keeps HTTP concerns (headers, cookies, CORS) distinct from streaming logic (SSE formatting, provider translation, retry logic).
How does the Electron desktop app reuse the Next.js codebase?
The electron/main.js process creates a browser window that loads the Next.js application. The electron/preload.js script exposes a secure IPC bridge to the renderer, allowing the same React components used in the web version to run in a desktop shell. The build pipeline outputs to a directory that Electron serves locally, ensuring feature parity between web and desktop without code duplication.
Where are LLM provider credentials and configurations managed?
Provider configurations are validated against schemas in src/shared/validation/providerSchema.ts. Credentials are handled within executor classes in open-sse/executors/ (such as default.ts or vertex.ts), which retrieve API keys from environment variables or secure storage. The src/lib/db/core.ts SQLite layer persists user-specific provider preferences and rate-limit counters.
How does the combo routing engine select which LLM provider to use?
The combo routing engine, implemented in open-sse/services/combo.ts, applies strategies defined in the request configuration. It can execute providers sequentially for fallback scenarios, parallel for latency optimization, or weighted for cost distribution. The engine intercepts requests after translation but before execution, allowing dynamic provider selection based on availability, token costs, or response quality metrics.
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 →