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

llmshim

v0.2.2

Published

TypeScript client for the llmshim proxy (multi-provider LLM API) — bundles a prebuilt binary and auto-starts it, or connects to a proxy you run yourself.

Readme

llmshim

Zero-runtime-dependency TypeScript/JavaScript client for the llmshim proxy.

Like the Python package, it bundles a prebuilt proxy binary for your platform and auto-starts it on the first request — nothing to run yourself. Pass an explicit baseUrl instead if you'd rather point it at a proxy you're already running (Docker, a shared server, llmshim proxy in another terminal).

  • Bundles a prebuilt binary per platform (macOS/Linux/Windows, x64/arm64) via optionalDependencies — the same pattern esbuild/swc/Turborepo use. No native dependency, no postinstall scripts.
  • Zero runtime dependencies otherwise (built-in fetch + ReadableStream + Node builtins for the auto-spawn, Node 18+).
  • Faithful to the proxy's OpenAPI contract (api/openapi.yaml).
  • Typed responses and a typed StreamEvent union.

Install

npm install llmshim

30-second quickstart

import { Client } from "llmshim";

const client = new Client(); // no baseUrl -> auto-starts the bundled proxy on first request

// Non-streaming
const res = await client.chat({
  model: "anthropic/claude-sonnet-4-6",
  messages: [{ role: "user", content: "What is Rust in one sentence?" }],
});
console.log(res.message.content);

// Streaming — an async iterator of typed events
for await (const ev of client.stream({
  model: "gpt-5.5",
  messages: [{ role: "user", content: "Write a haiku about the ocean." }],
})) {
  if (ev.type === "reasoning") process.stdout.write(`\x1b[2m${ev.text}\x1b[0m`);
  if (ev.type === "content") process.stdout.write(ev.text);
  if (ev.type === "error") throw new Error(ev.message);
}

// Discovery
console.log(await client.models());
console.log(await client.health());

Configuration

new Client({
  baseUrl: "http://localhost:3000", // connect to a proxy you're already running — disables auto-spawn
  headers: { authorization: "Bearer …" }, // sent on every request
  fetch: myFetch, // custom fetch (optional; defaults to global fetch)
});

Omit baseUrl to auto-spawn the bundled binary instead (see below). createClient(options) is also exported as an equivalent factory — both are fully synchronous; the auto-spawn happens lazily inside the first chat/stream/models/health call, not at construction time.

How the bundled binary works

npm install llmshim also installs one of five tiny optionalDependenciesllmshim-darwin-arm64, llmshim-darwin-x64, llmshim-linux-x64, llmshim-linux-arm64, or @sanjay920/llmshim-win32-x64 (the Windows one is scoped to sidestep npm's spam filter on unscoped *-win32-* names) — npm resolves the one matching your platform automatically via each package's os/cpu fields, so only ~8MB for your actual platform ever downloads. Each contains nothing but the prebuilt llmshim binary.

On the first chat/stream/models/health call on a Client constructed without baseUrl, the client finds that bundled binary (falling back to PATH, e.g. a cargo install llmshim), starts llmshim proxy on a free local port, waits for it to accept connections, and reuses that same process for every subsequent call in the same Node process — mirroring the Python client's _server.py. It's stopped automatically on process exit.

If no bundled binary is found and nothing is on PATH, the first request throws a clear error explaining how to install one or pass an explicit baseUrl.

Errors

Non-2xx responses throw a typed LlmshimError carrying status, code, and message (parsed from the proxy's { error: { code, message } } envelope):

import { LlmshimError } from "llmshim";

try {
  await client.chat({ model: "", messages: [] });
} catch (err) {
  if (err instanceof LlmshimError) {
    console.error(err.status, err.code, err.message);
  }
}

API

| Method | Endpoint | Returns | | --------------------- | ---------------------- | ------------------------------------ | | client.chat(req) | POST /v1/chat | Promise<ChatResponse> | | client.stream(req) | POST /v1/chat/stream | AsyncGenerator<StreamEvent> | | client.models() | GET /v1/models | Promise<ModelsResponse> | | client.health() | GET /health | Promise<HealthResponse> |

All request/response schemas are exported as TypeScript types (ChatRequest, Message, Config, ChatResponse, ResponseMessage, ToolCall, Usage, StreamEvent, ModelsResponse, HealthResponse, ErrorResponse, …).

Develop

npm install
npm run build   # tsc → dist/
npm test        # node --test, fully mocked (no network, no API cost)

scripts/manual-smoke-check.mjs is a manual (not automated) end-to-end check of the auto-spawn path against a real binary — see the comment at the top of that file for how to run it. It's excluded from npm test's auto-discovery and from the published package.

Publishing (maintainers)

Six packages publish together on every release, all via npm's OIDC trusted publishing (no tokens stored): the five platform binary packages (clients/typescript/packages/*) and this root package. Each needs a one-time Trusted Publisher configured at npmjs.com/package/<name>/access with:

  • Repository owner: sanjay920, repository: llmshim, workflow filename: release.yml, environment: release.

See .github/workflows/release.yml (npm-macos-binaries, npm-linux-x64-binary, npm-linux-arm64-binary, npm-windows-binary, npm jobs) and .claude/skills/release/SKILL.md.