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

kohra.js

v0.2.1

Published

Text-diffusion language models that generate in your browser: one JS file runs the denoising loop over ONNX Runtime Web on WebGPU.

Readme

कोहरा means fog. Generation starts as a fully masked canvas and clears, pass by pass, into text.

Install

| Path | How | |---|---| | Try it, nothing to install | Open the live demo (also on Hugging Face Spaces) | | Use it in your page | cp kohra.js your-app/ from this repo | | Import from a CDN | import { pipeline } from 'https://cdn.jsdelivr.net/npm/[email protected]/kohra.js' | | npm | npm install kohra.js |

The first load pulls the model (~1.5 GB fp16, ~0.7 GB q4) and compiles WebGPU shaders. Your browser caches both, so later loads start in seconds. kohra.js loads onnxruntime-web from a CDN and the tokenizer from Hugging Face itself, so there is no build step. A complete page:

<button id="go">Generate</button><pre id="out"></pre>
<script type="module">
import { pipeline } from './kohra.js';
const generate = await pipeline('text-diffusion', {
  model: 'https://huggingface.co/naklitechie/Qwen3-0.6B-diffusion-mdlm-ONNX/resolve/main/onnx/model_fp16_fused.onnx',
  tokenizer: 'naklitechie/Qwen3-0.6B-diffusion-mdlm-ONNX',
});
document.getElementById('go').onclick = async () => {
  const { text } = await generate('Explain WebGPU in one sentence.', { maxNewTokens: 128, steps: 128, stripThink: true });
  document.getElementById('out').textContent = text;
};
</script>

Serve it over https or localhost, because WebGPU needs a secure context: python3 -m http.server 8000. No config file and no API key. kohra imports onnxruntime-web and transformers.js from jsDelivr at runtime, so a bundler must leave those two https: imports external.

Why

You want to try text diffusion, the alternative to token-by-token generation, and every runtime you reach for is autoregressive. Transformers.js, onnxruntime-web and WebLLM all ship only a left-to-right decode loop. The published diffusion models need a Python server and a datacenter GPU.

kohra is the missing piece for the browser. It runs a few hundred lines of JS sampler over raw ONNX forward passes, plus ONNX exports of two small diffusion LMs that run on WebGPU. On a 121-token math answer, BD3LM with the KV cache now beats autoregressive decoding of the same 0.6B base: 3.0 s against 3.5–4.0 s. Diffusion always denoises its full canvas, so short answers still favour autoregressive decoding (benchmark in KOHRA.md). kohra is for running, measuring and building on text diffusion in the browser.

Watch the fog lift

DiffusionLM exposes the sampler and a callback for each step. x is the full token canvas, where masked positions equal lm.maskId. fresh holds the positions revealed in this step: colour them to animate the fog clearing.

import { DiffusionLM } from './kohra.js';
const lm = await DiffusionLM.from_pretrained({ model, tokenizer });
const out = await lm.generate(prompt, {
  maxNewTokens: 128, steps: 128, blockSize: 32,
  temperature: 0,      // 0 = argmax; >0 = Gumbel sampling
  threshold: 0.8,      // Fast-dLLM: reveal every position above this confidence; null = fixed steps
  onStep: ({ x, P, fresh, forward }) => render(x, P, fresh),
});
// out: { text, tokenIds, tokens, forwards, seconds, tokensPerSecond }

threshold: 0.8 is the one speed setting to turn on, and the demo's default. Across 3 prompts it cuts MDLM from 384 forward passes to 194 and BD3LM from 328 to 137, with the same math answer and fluent text. At 0.7 MDLM breaks on the math prompt. index.html is the live demo, built only on this API.

Pick a model

You get two models, each in fp16 and q4. The demo's model picker switches between all four.

| Model | Attention | Call with | Notes | |---|---|---|---| | MDLM | bidirectional | default | the original masked-diffusion checkpoint | | BD3LM | block-causal | blockCausal: true | higher scores: GSM8K 46.3 vs 29.3, HumanEval 46.3 vs 30.5; KV-cache graph ~2× faster |

For BD3LM, load the KV-cache graph. Each step then runs only the current block against a cache of finished blocks. Output is identical to the plain graph and about twice as fast:

const HF = 'https://huggingface.co/naklitechie/Qwen3-0.6B-diffusion-bd3lm-ONNX/resolve/main/onnx';
const lm = await DiffusionLM.from_pretrained({
  model: `${HF}/model_kv_fp16_fused.onnx`,          // or model_kv_q4f16_rtn_sym.onnx + graphOptimizationLevel: 'all'
  tokenizer: 'naklitechie/Qwen3-0.6B-diffusion-bd3lm-ONNX', kvCache: true,   // cache stays on the GPU
});
const { text } = await lm.generate(prompt, { blockCausal: true, threshold: 0.8 });

The plain q4 graphs are onnx/model_q4f16_rtn_sym.onnx; load them with graphOptimizationLevel: 'all'. They run on the stable onnxruntime-web 1.30.0 that kohra.js loads by default. q4 halves the download, and BD3LM q4 slips on arithmetic that fp16 gets right. To host your own export, serve the .onnx and .onnx.data side by side with permissive CORS. kohra finds the external-data file without configuration.

Commands

The Python export scripts need uv venv .venv && uv pip install --python .venv/bin/python torch "transformers==4.57.0" onnx onnxruntime onnxscript numpy huggingface_hub, plus git clone --depth 1 https://github.com/ZHZisZZ/dllm vendor/dllm for the BD3LM model code.

python3 -m http.server 8791                              # serve the demo and harnesses at localhost:8791
open http://localhost:8791/?arch=bd3lm                   # demo on a chosen model: mdlm | mdlm-q4 | bd3lm | bd3lm-q4
open http://localhost:8791/web/bench.html?mode=ar        # autoregressive Qwen3-0.6B baseline, same browser
.venv/bin/python scripts/export_onnx.py --fp16           # export MDLM to ONNX + parity check (export_bd3lm.py for BD3LM)
.venv/bin/python scripts/optimize_onnx.py                # fuse RMSNorm, then fp16 (required for WebGPU)
.venv/bin/python scripts/export_bd3lm_kv.py              # BD3LM block KV-cache graph: export, fuse, fp16, parity at each stage
.venv/bin/python scripts/push_to_hf.py --model mdlm --stage meta   # publish graph + tokenizer + card + kohra.js

Verify it yourself

npm test                                                 # 13 sampler tests on a fake ONNX session (Node >= 22, no install)
open http://localhost:8791/web/probe.html?model=<url>    # WebGPU logits vs the fp32 CPU ground truth
open http://localhost:8791/web/bench.html?mode=diff      # forwards, seconds and text per configuration (add &arch=bd3lm)

The probe fails a graph that returns non-finite or all-zero logits on WebGPU, or whose argmax disagrees with the fp32 reference. That is how the unfused fp16 graph was caught. The bench page produced the AR-vs-diffusion table in KOHRA.md, re-run on 2026-10-08 in thermal state nominal; the threshold and KV-cache tables come from the same kohra.js API run in that page. npm test runs the real kohra.js sampler against a fake session. It fails on a wrong commit order, a broken block-causal mask, a missing EOS trim, or a loop that stops making progress.

License

Apache-2.0. The published models carry the licences of their dllm-collection upstreams.

KOHRA.md (why, gate ladder, benchmark, gotchas) · reference/MDLM-algorithm.md (export recipe and WebGPU forensics)