npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

orbitrage

v0.6.1

Published

One-line observability + intelligent LLM routing for Node.js / TypeScript agents.

Downloads

338

Readme

orbitrage

One LLM gateway. Router + observability. One line.

Orbitrage is the proxy between your code and the model providers. Every request flows through it — so it sees the model you asked for, the model it routed to, the input messages, the output, tokens, cost, and latency. Pointing your OpenAI / Anthropic SDK at https://api.orbitrage.ai/v1 is the entire integration; this package is a 5-line convenience wrapper that does it for you and tags every call with a trace + user id so the dashboard groups them properly.

import { orbitrage } from "orbitrage";
import OpenAI from "openai";

await orbitrage.init({ apiKey: "orb_xxx_yyy" });   // 1 line of setup
                                                    //
const client = new OpenAI();                        // 2 lines of usage —
                                                    //   the OpenAI client auto-
                                                    //   points at the Orbitrage
                                                    //   gateway and adds trace
                                                    //   headers to every request.
await client.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "hi" }],
});

Open https://app.orbitrage.ai/workflows — every call shows up with model, tokens, cost, latency, and the full input/output.

Install

npm install orbitrage

Zero runtime dependencies. openai and @anthropic-ai/sdk are optional peers — install whichever clients you actually use.

What init() does

  1. Generates a stable trace id for this process. Every request carries it as x-orbitrage-run-id, so the dashboard groups all your agent's LLM calls into a single run.
  2. Patches the OpenAI and Anthropic class constructors to default baseURL to https://api.orbitrage.ai/v1 and add the trace headers via defaultHeaders. If you already pass baseURL or apiKey explicitly, your value wins.
  3. Sets OPENAI_BASE_URL as a safety net for code that constructs the client without any args.

That's all. No background timers, no span processors, no OTLP exports. The gateway sees every byte of the request and writes the routing decision, upstream response, tokens, cost, and latency directly to your project's data store. The proxy is the single source of truth.

Per-end-user graphs

If you're a B2B service handling traffic for many end-users (your customers' users), pass userId so the dashboard can partition every call inside one workflow:

await orbitrage.init({
  apiKey: process.env.ORBITRAGE_API_KEY,
  userId: currentUser.id,          // optional — your customer's user
});

Every subsequent LLM call is tagged with x-orbitrage-end-user-id. The dashboard uses it to build per-user flow graphs, cost breakdowns, and churn signals.

For long-running servers that switch end-users between requests, call orbitrage.setUser(userId) at the start of each request. The next OpenAI or Anthropic instance you construct picks up the new id.

Bring your own provider key (BYOK)

Save your OpenAI / Anthropic / Google / Groq key on the Models page. For models that match that provider, Orbitrage forwards the request to the provider with your key — your account is billed, our pooled credits are untouched. Routing decisions still appear in your dashboard with byok=true so you can see the split.

Forcing a specific model

Pass the model id verbatim — Orbitrage routes by explicit pin when the caller names a model:

await client.chat.completions.create({
  model: "claude-sonnet-4-6",      // explicit pin, no scoring
  messages: [...],
});

To let the router pick the cheapest model that meets the prompt's difficulty, pass the alias "auto" (or any of "router", "default", "orbitrage").

Backward compatibility

Decorators + lifecycle from v0.4 are kept as no-op shims so existing code compiles without changes:

import { workflow, task, flush, shutdown } from "orbitrage";

const planner = workflow("planner")(originalPlannerFn);
const run = task("run")(originalRunFn);

await flush();         // no-op — the gateway persists synchronously
await shutdown();      // no-op

The router captures the same data regardless of decorator markup; the decorators exist so v0.4 user code keeps importing.

How the workflow is determined

Every API key is minted for one workflow from the dashboard. The workflow your calls land under is whichever workflow your key belongs to — no appName argument required.

License

Apache-2.0