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

anyformer

v0.1.0

Published

One call to run a model in a browser tab: anyformer reads the Hub repo, probes the browser, and picks the back end (transformers.js, LocalMind's WebGPU kernels, diskformer, kohra) that fits the model's format, architecture and your GPU budget.

Readme

One call to run a model in a browser tab: anyformer reads the repo, probes the browser, and picks the back end that fits the model's format, architecture and your GPU budget.

Plain ES modules, no build step, no dependencies to install. Chromium with WebGPU (GGUF models also run on the CPU). Weights stay in the user's own browser storage; no account, no server, no telemetry.

license dependencies

Install

| How | Command | |---|---| | npm | npm install anyformer | | CDN | import { load } from 'https://cdn.jsdelivr.net/npm/[email protected]/+esm'; | | Copy | index.js and src/; nothing else is needed |

import { load } from 'anyformer';

const chat = await load('onnx-community/Qwen2.5-0.5B-Instruct', { budget: 2.5e9, onProgress: console.log });
for await (const { text } of chat.generate([{ role: 'user', content: 'What does a CPU do?' }], { maxNewTokens: 64 }))
  show(text);

Every session has run(input): chat messages for text generation (content a string, or blocks such as [{ type: 'image', image }, { type: 'text', text }] for Gemma 4 and Qwen3.5), a string or strings for embeddings, ImageData for vision, 16 kHz samples for speech. load(repo, { task }) picks a task when a repo has more than one. The first load downloads the weights into the browser; later loads read them from there. Each back end's runtime loads from jsDelivr only when that back end is chosen.

Try it

Serve the repo and open the workbench: pick a model, see which back end anyformer chose and why every other one refused, then chat (with an image for the vision models), compare embeddings, or detect objects; remove downloads.

python3 -m http.server 8000      # then open http://localhost:8000/examples/chat/

Why

You have a model id and a browser tab. Whether it runs depends on its format (ONNX, GGUF), its architecture, whether it is autoregressive or diffusion, and how much GPU memory the tab can take. Each runtime covers part of that, and you find out which part by failing to load.

anyformer asks every back end first. plan(repo) returns the model's description, the browser's capabilities and each back end's answer: yes with an estimate (GPU bytes, disk bytes, tok/s when measured), or no with a code and a reason. load(repo) runs the best yes.

Back ends

| Back end | Runs | Models | |---|---|---| | transformers | transformers.js 4.3.1: text generation, image and audio chat (Gemma 4, Qwen3.5), embeddings, speech to text, detection, classification, depth, segmentation | ONNX repos in the onnx-community / Xenova layout | | kohra | kohra, text-diffusion over onnxruntime-web | MDLM and BD3LM repos tagged text-diffusion | | localmind | LocalMind's hand-written WebGPU kernels, the whole model on the GPU | any LFM2 / LFM2.5 GGUF; Gemma 4 E2B / E4B QAT-mobile; Ternary Bonsai 2 | | wllama | llama.cpp in WebAssembly: WebGPU when the budget holds the model, the CPU otherwise (no WebGPU needed) | any GGUF up to about 3.6 GB that no engine above covers; files over 2 GB are split into OPFS shards once | | diskformer | diskformer engines: weights in OPFS, only what a step needs on the GPU | Gemma 4 26B-A4B (from 2.5 GB), Qwen3.6 35B-A3B (from 4 GB) |

Each runtime loads from an exact version or commit in src/sources.js; set a back end's .source (for example kohraBackend.source) to load another copy. BACKENDS lists the back ends load() asks by default: each joins after its browser test passes.

When no back end can run it

load() throws an AnyformerError with code NO_BACKEND and the plan, naming each back end, its code and its reason. Codes are a closed set, each with one remedy in REFUSALS: format, model, task, webgpu, f16, opfs, budget (with need, the budget that would pass) and threw. Every other failure is an AnyformerError too, with a code from ERROR_CODES (LOAD_FAILED, BUDGET_TOO_SMALL, ABORTED, EXECUTION_FAILED, INVALID_ARGUMENT, DISPOSED); check it with isAnyformerError(e, code). A session runs one generate() at a time, in call order.

Commands

plan(repo, { budget, task })      // what would run it, and why the others would not; loads nothing
load(repo, { budget, task, maxCtx, onProgress, signal })  // → { backend, task, plan, run(input), generate?, dispose() }
pipeline(task, repo, { budget })  // transformers.js's call shape: gen(messages) → [{ generated_text }]
probe()                           // WebGPU, shader-f16, subgroups, limits, OPFS quota, memory64
describe(repo)                    // Hub repo → formats, architecture, task, tags, files
resolve(model, caps, backends, { budget })  // rank back ends for a described model
stored() · remove(repo)           // what is downloaded in this browser; delete one
MODELS.chat.DEFAULT               // models that pass a browser test; load(MODELS.chat.GEMMA4_26B_A4B) works too
registerTools()                   // publish the agent face (below)

Agents get the same calls as tools (anyformer_models, _probe, _plan, _load, _generate, _sessions, _unload, _stored, _remove) through WebMCP's navigator.modelContext where the browser has it and window.anyformer.tools otherwise; anyformer_load loads nothing until the caller accepts the plan's disk bytes, and anyformer_remove deletes nothing without confirm: true.

Verify it yourself

npm test                                   # Node: probe, describe, resolver, back-end verdicts, agent face
npm run test:browser -- probe              # headless Chrome: WebGPU, f16, OPFS
npm run test:browser -- transformers       # Qwen2.5-0.5B answers on topic
npm run test:browser -- kohra              # Qwen3-0.6B MDLM answers on topic
npm run test:browser -- embed             # MiniLM embeddings rank a paraphrase above an unrelated sentence
npm run test:browser -- detect            # DETR finds both cats in cats.jpg
npm run test:browser -- examples/chat/index.html --query "auto=1"   # the workbench loads and answers
npm run test:browser -- pipeline --port 8192 --profile ~/.cache/anyformer-chat-profile   # pipeline() on a GGUF
npm run test:browser -- store             # list a download, remove it
npm run test:browser -- chat --query "repo=LiquidAI/LFM2.5-1.2B-Instruct-GGUF"   # a LocalMind engine
npm run test:browser -- vision --query "repo=onnx-community/Qwen3.5-4B-ONNX-OPT"   # names the two cats
npm run test:browser -- diskformer-chat    # Gemma 4 26B-A4B at 2.5 GB: 9/9 replies identical to llama.cpp b9830

The browser tests fail a reply that is off topic or repeats itself, and diskformer-chat fails any reply that differs from llama.cpp's by one character. Only Apple silicon (M4 Pro, Chrome) has run them. Not tested yet: audio input blocks, abort mid-reply, speech / classification / depth / segmentation in a browser, any machine other than the M4 Pro, and Qwen3.6 35B-A3B (it needs more than that machine's 24 GB).

License

MIT. Spec and agent contract: SPEC.md · depends on diskformer.js · kohra · LocalMind