Brimkern vs WebLLM: two ways to run an LLM in the browser
Both run a large language model client-side on WebGPU, with no server and no API key. They differ on one decisive point: what you must do to a model before it can run.
Numbers below were measured between 2026-08-13 and 2026-08-15, same laptop GPU, same model (DeepSeek-R1-Distill-Qwen-7B, int4), same prompt. Nothing here is an estimate — and that model is in the catalogue, so you can run it yourself.
Measured, side by side
| What | Brimkern | WebLLM |
|---|---|---|
| Prefill (reading the prompt)Same 7B int4 model, same laptop GPU. Our hand-written tiled WGSL matmuls hold ~1 TFLOP/s on these shapes. | 47,2 tok/s | 18,7 tok/s |
| Decode (writing the answer)WebLLM is ahead here, and we say so. Ours was re-measured on 2026-08-15 after making RMSNorm parallel per row: 8.1 → 10.2 tok/s on this exact model (two passes: 9.7 and 10.7). The gap narrowed — 1.37× instead of 1.46× — but it is still a gap, and closing it is the current work. | 10,2 tok/s | 14,0 tok/s |
| Model preparationThis is the structural difference. We read single-file GGUF straight from Hugging Face; WebLLM needs weights pre-compiled into its own artifact first. | none — paste author/model | compile with MLC/TVM |
| Reload from cache (4.7 GB)Our .brik container stores one layer per contiguous HTTP range, so a reload is resumable and works offline. | 15,8 s | — |
| Catalogue & maturityWebLLM has years of production use, auto-tuned kernels and an OpenAI-compatible API. If you want a curated list of models that just work, it is the safer pick today. | younger, fewer presets | large, battle-tested |
| Kernels checked at loadEvery hand-written kernel validates itself against a CPU reference when the engine starts, and falls back to a simpler path if a GPU miscompiles it — a real failure mode on the variety of GPUs the web runs on. Each one also has a URL kill-switch to isolate it. | CPU reference + fallback | trusted as compiled |
The difference that decides
WebLLM: compile, then run
Weights go through the MLC/TVM toolchain and come out as a WebLLM artifact. That step buys auto-tuned kernels per architecture — and costs you a build every time you want a model that is not already in the catalogue.
Brimkern: read the file the Hub already hosts
Paste author/model and it runs: the quantization is picked for you, the tokenizer is rebuilt from the file itself, and the weights stream in by HTTP ranges. Nothing to compile, nothing to host, nothing to configure.
Which one should you use?
- You want to try a model you just found on Hugging Face, today, without a build step → Brimkern.
- You ship a product on a fixed, curated model list and want the most battle-tested runtime → WebLLM.
- Your widget stays open for a long conversation and memory must not creep → Brimkern — the catalogue includes recurrent models (RWKV-7) whose state is a fixed ~1 MB instead of a KV cache that grows with every token.
- You need to host the weights yourself, on your own domain → Brimkern — convert a GGUF to .brik in the browser, put the file on any static host, and it streams by HTTP range from there.
- You need an OpenAI-compatible API surface out of the box → WebLLM.
WebLLM is an excellent project and the reason in-browser inference is taken seriously at all. This page compares engineering trade-offs, not teams. If a number here is wrong, tell us — the benchmark harness is in the repository.
Brimkern — open WebGPU engine, built by Romain Khanoyan. Local AI, WebGPU, on-device engines.