minidraco
v0.3.0
Published
A fast pure-TypeScript Draco mesh decoder, drop-in DRACOLoader replacement for Three.js.
Readme
🐲 minidraco
A fast, pure-TypeScript Draco mesh decoder with a drop-in
DRACOLoader for Three.js — no wasm to host or fetch, and a worker pool
so decoding never blocks the main thread.
Usage
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { MinidracoLoader } from 'minidraco/three'
const gltfLoader = new GLTFLoader()
gltfLoader.setDRACOLoader(new MinidracoLoader())
gltfLoader.load('model.glb', gltf => scene.add(gltf.scene))A drop-in for THREE.DRACOLoader, no cast needed. Decoding runs in a worker pool by default, with
a main-thread fallback. Options:
new MinidracoLoader({ workers: false }) // decode on the main thread
new MinidracoLoader({ workerLimit: 8 }) // pool size (default 4)Or decode a raw bitstream without Three.js:
import { decodeDracoMesh } from 'minidraco'
const mesh = decodeDracoMesh(new Uint8Array(bytes))Features
- Every Draco triangle mesh — all encodings, prediction schemes, and attribute types.
- Bit-identical to the official wasm decoder, verified in the tests.
- No point clouds (glTF Draco is always meshes).
Performance
Median across a 19-model corpus vs draco.js and the official draco3d wasm decoder (full results in BENCH.md):
| benchmark | vs draco.js | vs draco3d wasm |
| --------------------------------------------- | --------------- | --------------- |
| single-threaded decode — bun (JSC) | ⚪ even | 🟢 1.13× faster |
| single-threaded decode — Chrome (V8) | ⚪ even | 🟢 1.50× faster |
| GLTFLoader.parse, worker pool — Chrome (V8) | 🟢 1.23× faster | 🔴 1.10× slower |
On par with draco.js, faster than the wasm decoder single-threaded, and competitive in a real
GLTFLoader.parse with the main thread left free.
🟢 Cold start is the real win, and no warm benchmark shows it: there's no draco_decoder.wasm
to fetch and compile before the first decode, so the first model on screen appears sooner.
Download size
Over the wire (brotli): ~23 KB ships in your app bundle. With the worker pool on (default) the
browser also fetches a ~22 KB worker chunk on the first decode — ~45 KB total; workers: false
skips that fetch. draco.js ~22 KB, draco3d wasm ~76 KB — the wasm is a separate file you
must host, while the JS decoders ship inside your bundle.
Monorepo
library/— theminidracopackageexample/— Next.js + React Three Fiber demo with an in-browser benchmark at/bench
bun install
bun dev # watch build + demo
bun run all # format, lint, typecheck, tests
bun run bench # cross-decoder benchmarkLicense
MIT — derived from mrdoob/draco.js (MIT), implementing Google's Draco bitstream (Apache-2.0).
