Adaline Gateway: A Local TypeScript Router for 300+ LLM Providers
The only fully local production-grade Super SDK that provides a simple, unified, and powerful interface for calling more than 200+ LLMs.
At a glance
- What is it?
- Adaline Gateway is an MIT-licensed TypeScript SDK that normalises chat and embedding calls across OpenAI, Anthropic, Bedrock, Vertex and others without running a proxy. The unification is real, but the provider matrix is uneven and the README stops before the hard parts.
- Who is it for?
- Adopt Adaline Gateway if you are writing TypeScript and want one request shape across several providers without standing up a proxy, and if the providers you need are on the chat side of the table. Do not adopt it if embeddings are central to your stack, since Anthropic, Google AI Studio, Bedrock, Groq, Together AI and Open Router are marked as chat-only in the provider table, and Voyage is embedding-only.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 48 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem: provider SDKs do not agree on anything
Every provider ships its own client, its own message shape, its own naming for token limits, and its own error format. If you call OpenAI and Anthropic from the same service, you end up maintaining two request builders, two response parsers, and two retry policies that drift apart over time. Adaline Gateway's answer is a single request type defined in @adaline/types, with per-provider packages that translate to and from it. The README describes the project as a Super SDK providing a unified interface for calling more than 300 LLMs, and the package split makes the intent clear: @adaline/gateway holds the orchestration, @adaline/types holds the shared vocabulary, and @adaline/openai, @adaline/anthropic, @adaline/google, @adaline/bedrock and the rest hold the translation layers. The target user is a TypeScript engineer who already has provider accounts and wants the routing logic to live in their own process. It is not aimed at someone who wants a hosted endpoint to point a browser at.
Not a proxy: where the code and the credentials actually sit
The README repeats the claim that the library is fully local and not a proxy, and the quickstart backs it up. You construct a Gateway instance in your own process, construct a provider instance such as new OpenAI(), and pass an apiKey directly into chatModel(). There is no sidecar to deploy and no Adaline-hosted hop between your service and the provider. That matters for two reasons. First, latency: the only network call in the chat path is the one to the provider, and the response object exposes latencyInMs so you can see it. Second, data handling: prompts and API keys stay inside your runtime, which is often the deciding factor when a hosted router is not acceptable. The trade-off is that operational responsibility moves to you. Key rotation, egress rules, and per-provider rate limits are your problem, because nothing sits in front of your process to absorb them.
The request path from completeChat to a provider response
The mechanism visible in the README is a translation pipeline. You build a ConfigType by calling Config().parse() on a plain object, and you build a MessageType array where each message has a role and a content array, and each content entry has a modality and a value. You pass the model handle, the config, the messages and a tools array into gateway.completeChat(). What comes back is not just the model output. The result carries provider.request and provider.response, which the README labels as the HTTP request sent to the provider and the HTTP response from the provider, alongside request and response in Gateway types, a cached boolean, and latencyInMs. That split is the most useful design decision in the library, because when a provider rejects a payload you can inspect the exact body the SDK produced rather than guessing which normalisation step mangled it. Streaming uses the same inputs through gateway.streamChat(), which returns an async iterable of chunks. Embeddings follow a parallel shape through gateway.getEmbeddings(), taking an embeddingRequests object with a modality of text and a requests array of strings.
Installing the core, then only the providers you call
Setup is two npm installs. The core is npm install @adaline/gateway @adaline/types. Provider packages are separate and described in the README as optional dependencies installed as needed, with the example npm install @adaline/openai @adaline/anthropic @adaline/google @adaline/open-router @adaline/bedrock. Keeping provider clients out of the core install is a sensible choice for bundle size, and the README links a bundlephobia badge for the core package. The quickstart then wires the pieces: new Gateway(), new OpenAI(), openai.chatModel({ modelName: "gpt-4o", apiKey: OPENAI_API_KEY }), and Config().parse({ temperature: 0.7, maxTokens: 300 }). The embedding example uses openai.embeddingModel({ modelName: "text-embedding-3-large", apiKey: OPENAI_API_KEY }) with a config of encodingFormat: "float" and dimensions: 255. Model discovery is code, not a doc page: openai.chatModelLiterals() returns an array of chat model names, openai.embeddingModelLiterals() does the same for embeddings, and openai.chatModelSchemas()["o4-mini"] returns a schema exposing name, description, maxInputTokens, maxOutputTokens, roles, modalities and config.
The provider table is the real constraint
The headline count is more than 300 LLMs, but the table in the README lists twelve provider entries, and the chat and embedding columns do not line up. OpenAI, Google Vertex, xAi and Azure OpenAI are marked for both chat and embedding models. Anthropic, Google AI Studio, AWS Bedrock, Groq, Together AI, Open Router and the custom OpenAI-like entry are chat only. Voyage is embedding only. So a plan that assumes one gateway call shape covers both modalities everywhere will not survive contact with the table. There is also a distinction between the provider list and the model count: the 300+ figure refers to models reachable through those providers, and the README does not break that number down per provider. If your workload is embedding-heavy, the practical set is narrower than the marketing line suggests. The custom OpenAI-like provider entry is the escape hatch for anything not listed, and the README also mentions plug-and-play custom providers for local and custom models, but it does not show a worked example of implementing one.
What the README does not settle
Several claims appear in the feature list without a corresponding example. Batching is described as batching for all requests with custom queue support, caching is described as supporting custom cache plug-ins, and callbacks are described as hooks for instrumentation, with OpenTelemetry integration mentioned as a feature. The quickstart never constructs a cache, a queue, a callback or a tracer, so the configuration surface for those four features is not visible in the material available here. That is not evidence they are broken. It does mean you should treat the plugin interfaces as something to read in the repository source before you design around them. The same applies to retries: automatic retries with exponential backoff is listed, but no option name, default count or backoff base is given. The result object's cached boolean tells you whether a response came from cache, which implies the cache sits in the request path rather than beside it, but the README does not state where cache entries are stored by default.
How this differs from LiteLLM and from calling provider SDKs directly
LiteLLM is the comparison most engineers will reach for, and the difference is architectural rather than cosmetic. LiteLLM is commonly run as a Python proxy service, so your application sends OpenAI-shaped HTTP requests to a local or hosted endpoint and the proxy handles provider translation, key management and spend tracking. Adaline Gateway inverts that: the translation happens inside your TypeScript process, and there is no endpoint. If your stack is Node or Bun and you do not want another service to deploy, monitor and secure, the in-process model removes a moving part. If you need a language-agnostic gateway that Python, Go and Ruby services can all call over HTTP, the in-process model is the wrong shape entirely, and a proxy is the correct answer. The other alternative is using @adaline/openai, @adaline/anthropic and friends without @adaline/gateway at all, which keeps you on each vendor's native types and gives up the unified Config and Message shapes along with the cross-provider result fields.
Licence, maintenance and the cost of staying current
The project is MIT licensed, which permits commercial use and modification, and the repository is not archived. The release history shows v1.12.1 on 2026-07-29, v1.12.0 on 2026-07-11 and v1.11.26 on 2026-06-09, so patch and minor releases arrive on a rough monthly cadence with the most recent one landing the same day as the last push. That cadence is the maintenance cost you inherit. Model names, token limits and config schemas change when providers change them, and each provider package has to track its vendor. The mitigation is built in: chatModelLiterals() and chatModelSchemas() let you assert at startup that the models and limits you depend on are still present in the version you installed, so a dependency bump that drops or reshapes a model fails in your test run rather than in production. This is a description of the licence terms, not legal advice; check the LICENSE file and your own counsel for anything beyond that.
Editorial conclusion
Adopt Adaline Gateway if you are writing TypeScript and want one request shape across several providers without standing up a proxy, and if the providers you need are on the chat side of the table. Do not adopt it if embeddings are central to your stack, since Anthropic, Google AI Studio, Bedrock, Groq, Together AI and Open Router are marked as chat-only in the provider table, and Voyage is embedding-only. Before committing, run chatModelSchemas() for each model you plan to call and check the config schema, maxInputTokens and modalities fields, because those are the values the SDK will actually validate against.
Community notes