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

omniglyph

v1.3.1

Published

Context-as-image compression proxy for LLMs: renders bulky context (system prompt, tool docs, history) as dense PNG pages with exact per-provider billing math (Anthropic/OpenAI/Gemini). Node and Cloudflare Workers. Part of the OmniRoute family.

Downloads

17,388

Readme

🖼️ OmniGlyph — Context as Image

Cut your Claude bill by 59–70% by rendering bulky context as dense PNG pages — the same content, in a fraction of the tokens.

Models bill text per token, but bill an image by its dimensions — not by how much text is inside it.

59–70% Bill Cut 10x Fewer Tokens 100% Read Accuracy Zero Confabulations

CI npm version License: MIT Node ≥18

Part of the OmniRoute family · 🌐 All languages

chart: characters a frontier context window holds, 2018–2026 — every vendor line tops out near the ~4M chars a 1M-token window holds as text; the same Fable 5 1M window through OmniGlyph images holds a measured ~18M chars, 4.54× the text ceiling

Eight years of context growth, in characters. Every text line tops out near ~4M chars (a 1M-token window at ~4 chars/token); the orange point is the same Fable 5 1M window read through OmniGlyph images — ~18M chars at the measured 18.16 chars/vision-token, 4.54× the text ceiling. The density and multiplier are measured from a live render at generation time, not hand-typed: regenerate with npx tsx scripts/gen-context-chart.ts (source).


📊 The numbers — measured, not estimated

| metric | result | receipt | |---|---|---| | End-to-end bill reduction | 59–70% | production trace, 13,709 requests | | Tokens per converted block | 10× fewer (28,080 chars: 14,040 → 1,460 tokens) | billing sweep | | Billing-formula accuracy | residual zero across 22 count_tokens probes, 2 models × 2 tiers | benchmarks/billing-sweep/results/ | | Exact-read accuracy, production config | 30/30 (100%) on Claude Fable 5 | density frontier | | Silent confabulations in ~300 read probes | 0 — every miss abstains as ILEGIVEL | benchmarks/density-frontier/results/ |

Model scorecard (can it read dense renders? n=30 per arm, deterministic scoring):

| model | reading | verdict | |---|---|---| | Claude Fable 5 | 100% exact | ✅ production target | | Claude Opus 4.8 | 77–87% at 4× glyph size | ⚠️ opt-in safe mode (savings drop to ~2×) | | GPT-5.5 | 0/60 — and inflates its answers ~40× trying | ❌ blocked by the gate, with proof | | Gemini 2.5-flash | 0/26 — and confabulates instead of abstaining | ❌ blocked (partial test, quota-limited) |

The advantage is Fable-specific today — other vision encoders don't resolve dense glyphs yet. The benchmark harness re-tests any new model in one command.

🤔 Why OmniGlyph?

Every long-running agent session drags the same dead weight on every request: the system prompt, tool docs, and old history — re-billed per token, every turn. OmniGlyph is a local proxy that rewrites those bulky parts into dense PNG pages before they leave your machine:

  • Exact billing math, not heuristics — it computes the provider's real image-token formula (measured to residual zero) and converts only when the math wins.
  • Fail-closed by design — models that can't read dense renders are blocked by a gate, with benchmark receipts. No silent quality loss.
  • Private & local-first — the rewrite happens on 127.0.0.1; nothing extra is sent anywhere.
  • Reproducible — every number above has a receipt in benchmarks/*/results/, re-runnable in one command.

⚡ Quick Start

npx omniglyph                                     # proxy on 127.0.0.1:47821
ANTHROPIC_BASE_URL=http://127.0.0.1:47821 claude  # point Claude Code at it

Quickstart: start the proxy, check the dashboard, point Claude Code at it

Works both ways:

  • API key (pay per token): your bill drops 59–70% end-to-end.
  • Subscription session: you don't pay less, but usage limits are counted in tokens — so your limits stretch ~2–3×.

Dashboard at http://127.0.0.1:47821/: tokens saved, every text→image conversion side by side, kill switch, live model chips. Responses stream normally — only the request is compressed, never the model's output.

🔌 Use with Claude clients

Start the proxy in one terminal, then point the client at it.

Claude Code CLI (macOS/Linux):

npx omniglyph
ANTHROPIC_BASE_URL=http://127.0.0.1:47821 claude

Claude Code CLI (Windows PowerShell):

npx omniglyph
$env:ANTHROPIC_BASE_URL = "http://127.0.0.1:47821"
claude

Claude Desktop uses the same ANTHROPIC_BASE_URL environment variable for its bundled Claude Code runtime — start omniglyph first, then launch Claude Desktop from an environment where ANTHROPIC_BASE_URL is set to http://127.0.0.1:47821.

🖥️ The dashboard

A full local dashboard ships inside the package — offline, single-file, zero external requests. Six pages, updated live over SSE as requests flow:

Overview: mission-control KPI cards, savings sparkline and live event feed

  • Overview — mission control: savings %, $ saved, latency p95, cache hits, errors, live feed.
  • Live Flow — the pipeline as a node graph: client → gate → renderer / passthrough → API, with a particle per real request.
  • Telemetry — a token/$ odometer and a live request timeline; click any request to see exactly which parts became images and read the source text behind every page.
  • Benchmarks — the harness receipts rendered from benchmarks/*/results/, one row per model·config experiment, and run the benchmarks from the UI: $0 dry-runs stream their output live; live runs stay gated behind your API key plus an explicit cost confirmation.
  • Sessions / History — top sessions by tokens saved and every event on disk.

| Live Flow | Benchmarks | |---|---| | The request pipeline as a live node graph | Benchmark receipts and in-UI dry-runs |

Telemetry: odometer and live request timeline

⚙️ How it works

bulky request block ──► profitability gate ──► reflow + render (1-bit 5×8 atlas)
                       (exact billing math)     ──► 1568×728 PNG pages ──► splice back, cache-friendly
  • Billing is computed exactly, before converting: Anthropic bills ⌈w/28⌉ × ⌈h/28⌉ + 4 tokens per image (28 px patches — measured to residual zero). A full page carries 28,080 chars for 1,460 tokens ≈ 19 chars/token, vs ~2 chars/token for dense text. The gate converts only when the math wins.
  • What converts: the static system prompt + tool docs, old collapsed history, large tool outputs.
  • What never converts: your messages, recent turns, the model's output, sparse prose, byte-exact values (hashes/IDs ride alongside as text), and any model that failed the reading benchmark.

Opt-in flags

All off by default — the compression path above is unchanged unless you set them. omniglyph --help lists every flag.

  • OMNIGLYPH_GUARD_SECRETS=text|redact — keep API keys, tokens, and other credentials out of rendered images: text never images a block that holds one, redact masks it in place. Never alters what the upstream API receives.
  • OMNIGLYPH_KEEP_SYSTEM_TEXT=1 — never image the session config (system prompt, tool docs, reminders); tool outputs and old history still convert. Guards against Anthropic's refusal classifier on system-shaped images.
  • OMNIGLYPH_MODELS — comma-separated model bases to image (default claude-fable-5,gpt-5.6; off disables). Grok is supported opt-in on the OpenAI-compatible wire but stays fail-closed: text-only until acked via OMNIGLYPH_UNVERIFIED_MODELS=grok-4.5, pending its own reading receipt.

📚 Library use (no proxy)

Everything the proxy does per request is also a documented, importable API:

import { renderTextToImages, transformAnthropicMessages } from "omniglyph";

// Render any text to dense 1-bit PNG pages
const { pages } = await renderTextToImages(bigToolOutput, { reflow: true });
// pages[i].png: Uint8Array · pages[i].width × pages[i].height

// Or run the full request transform yourself — gate, billing math and all
const { body, applied, reason } = await transformAnthropicMessages({
  body: requestBytes,           // the raw /v1/messages JSON body
  model: "claude-fable-5",
});

options.keepSharp(block) pins blocks as text; options.emitRecoverable returns the originals of imaged blocks. The exact billing math ships at the package root too (anthropicImageTokens, resolveAnthropicVisionTier, openAIVisionTokens) — that is what OmniRoute consumes. Pure-JS runtime (Node and edge/Workers). Full surface: src/core/index.ts.

📤 Offline export — no proxy, no Claude Code

Not on Claude Code? Render the context to PNG pages locally and paste them into Cursor, ChatGPT, or any chat that accepts image uploads. No proxy, no API key, no account wired up:

npx omniglyph export --include "*.ts" src/   # render a folder to image pages
cat big.log | npx omniglyph export --stdin   # …or pipe any text through

You get one folder with everything to drop into the chat:

OmniGlyph-export-<hash>/
  page-001.png …   the rendered image pages — attach these
  factsheet.txt    verbatim precision tokens (paths, SHAs, ids, numbers)
  prompt.txt       a paste-ready instruction that points the model at the pages
  manifest.json    metadata + the text-vs-image token report (% saved)

--git renders your uncommitted diff, --diff <ref> a commit range, --open reveals the folder (macOS). It all runs on your machine — the export path never starts the proxy and never calls a model. Run omniglyph export --help for every flag.

🧭 The honest part

  • It is lossy. Byte-exact recall from images is unreliable by nature. Mitigations shipped: exact identifiers travel as text next to the image, and the measured production config produced zero silent confabulations — failed reads abstain.
  • Only Fable 5 is approved today, with receipts. GPT-5.5 and Gemini 2.5-flash measurably cannot read dense renders; Opus 4.8 needs 4× bigger glyphs. The gate enforces this.
  • We found and avoided a billing trap: the high-resolution image tier bills 3.3× more per page, but the vision encoder doesn't receive the extra resolution — bigger pages read worse. Measured, documented in docs/benchmarks/BENCHMARKS.md, not enabled.
  • Prices change; the durable metric is the token cut, which the proxy logs per request against a free count_tokens counterfactual.

🧠 FAQ

I enabled it mid-session and my usage spiked — why? A session that ran without OmniGlyph has its entire prefix cached by Anthropic as text at the 0.1× read rate; the first imaged request would re-pay all of it as a fresh 1.25× cache write in a single prompt. The proxy guards against this: a session it has never imaged feeds that one-prompt cost into the break-even gate and only switches to images when it still wins — otherwise the session stays as text, and the savings start with your next new session.

Is the 59–70% end-to-end, or only on the requests it touched? End-to-end — the whole bill. Most compression tools report savings only on the slice they touched, which flatters the number. Our denominator is every request: the small ones the gate correctly left untouched, all cache writes and reads, and all output tokens (which the proxy never compresses). Compressed-only runs higher and is quoted separately, never as the headline.

How is the saving measured? Both sides of the same request, at the same moment. For every /v1/messages POST the proxy fires a free count_tokens probe on the original uncompressed body (the counterfactual) in parallel with the real forward, and reads the provider's actually-billed usage block off the response — both land in the same event row. Cache pricing is applied identically to both sides, so the caching discount cancels and can't be double-counted as "savings". The formula lives in src/core/baseline.ts; re-derive it from your own events log.

Why would a miss be a confabulation instead of a read error? Because model vision is not OCR: the page becomes patch embeddings, never discrete characters, so there is no per-glyph confidence to fail loudly on — when pixels underdetermine a glyph, the language prior fills the gap with something plausible. That mechanism is exactly why OmniGlyph is fail-closed about it: byte-exact values always ride as text next to the image, models that misread are blocked by the gate, and the measured production config produced zero silent confabulations in ~300 read probes — failed reads abstain.

What about byte-exact work (hashes, IDs, secrets)? Recent turns and exact identifiers stay text by design. For workloads that are all byte-exact, route them to a non-allowlisted model (e.g. a subagent on another Claude model) — anything outside the allowlist passes through byte-identical, untouched.

Didn't DeepSeek-OCR settle whether this works? It proved the channel works — with an encoder/decoder pair trained for the job. The skepticism dates from when no stock production model could read dense renders; that changed, and the model scorecard above shows exactly who reads them today, with receipts. The benchmark harness re-tests any new model in one command — the gate follows the data, not the hype.

Can I use it without Claude Code — Cursor, ChatGPT, a plain pipe? Yes, two ways. As a proxy it works with any client that lets you set the API base URL (ANTHROPIC_BASE_URL, or the OpenAI base URL) — Claude Code, your own scripts, anything HTTP. And for tools that can't proxy, the Offline export above renders the context to PNG pages you paste in by hand — omniglyph export --stdin even reads straight from a Unix pipe.

How does it actually turn text into an image? It reflows the text and paints it with a 1-bit 5×8 pixel glyph atlas onto dense 1568×728 PNG pages — one bit per pixel, no anti-aliasing, so the model bills the page by its dimensions, not by how many characters are inside. How it works above has the pipeline; the benchmarks doc has the geometry and why denser isn't always cheaper.

🔬 Reproduce every number

pnpm install && pnpm test                                     # full suite
node benchmarks/billing-sweep/run.mjs --dry-run               # billing predictions, $0
pnpm exec tsx benchmarks/density-frontier/run.ts --dry-run    # cost table, $0
# with keys: ANTHROPIC_API_KEY / OPENAI_API_KEY / GEMINI_API_KEY (or --via-cli for a Claude Code subscription)

The two benchmark harnesses running in dry-run mode

Full methodology and every result table: docs/benchmarks/BENCHMARKS.md. Raw per-answer receipts: benchmarks/*/results/*.jsonl.

🚀 The OmniRoute family

OmniGlyph also ships as a native compression engine inside OmniRoute — the free AI gateway. There it runs as the omniglyph engine (standalone single mode or stacked with the other engines), with fail-closed gates and image-aware token accounting.

🛠️ Tech Stack

| layer | tech | |---|---| | Language | TypeScript (strict), ESM | | Runtime | Node ≥18 · Cloudflare Workers (wrangler.toml) | | Rendering | own 1-bit glyph atlas (Spleen/Unifont-derived, licenses in assets/) → PNG | | Tests | Vitest — TDD, plus docs-integrity and rebrand guards | | Benchmarks | benchmarks/ harnesses (billing-sweep, density-frontier) with JSONL receipts |

Project layout

| path | what | |---|---| | src/ | the proxy: transform pipeline, exact billing per provider, renderer, hosts (Node + Cloudflare Workers) | | benchmarks/ | the harnesses that produced every number above — re-runnable | | docs/ | BENCHMARKS · ARCHITECTURE · ROADMAP |

📧 Support & Community

🙏 Acknowledgments

OmniGlyph stands on the shoulders of one project in particular — this section is our permanent thank-you.

| Project | How it shaped OmniGlyph | |---|---| | pxpipe · teamchong | The discovery this whole project is built on. pxpipe proved, with receipts, that a production LLM's vision channel can carry dense textual context at a fraction of the token cost — and that the conversion must be decided per-request by exact billing math, never by vibes. The dense 1-bit rendering, the profitability gate, the count_tokens counterfactual, the fail-closed model allowlist, and the "measure before you claim" documentation culture were all pioneered there. OmniGlyph descends directly from that codebase (MIT — the original copyright line stays in our LICENSE). | | Spleen · Frederic Cambus | The 5×8 bitmap font family our dense 1-bit glyph atlas derives from (license in assets/). | | GNU Unifont · Unifoundry | Coverage for the glyphs beyond Spleen's range in the same atlas (license in assets/). |

If you find OmniGlyph useful, go star the upstream too — the discovery was theirs. 🙏

📄 License

MIT — see LICENSE.