Draco geometry compression in pure Rust, with the file formats and glTF scene handling around it. Nothing here links the original library; bitstream compatibility is a property of the implementation, checked against reference fixtures and the upstream binaries themselves.
This project is independent and is not an official Google Draco release.
Draco 3D Studio — a converter and
viewer for the crates below, running at filyus.github.io/draco-rust. No
upload, no server: the WASM modules do the work in the page, and the files never
leave the machine.
Open an OBJ, PLY, STL, DRC, FBX or glTF/GLB asset and it reports what the file actually contains — hierarchy, materials, skins, morph targets, animation clips — renders it, and exports any of them back out, with Draco compression optional along the way.
Converting between formats loses things, and the per-format conversion rules say which: what survives an FBX to glTF trip, what has no equivalent to survive into, and where the viewer's limits are narrower than the exporter's.
The codec: Draco bitstream encode and decode for triangle meshes and point clouds, and the geometry model everything else speaks.
Formats: OBJ, PLY, STL, binary and ASCII FBX, plus strict glTF/GLB container, resource and accessor contracts.
Whole glTF 2.0 and pinned 2.1-draft documents, losslessly: typed scene views, packed-geometry read/write, document-preserving Draco compression, GLB v2/v3.
Full glTF applications should depend on draco-gltf. draco-io deliberately
exposes no glTF scene API — it is the layer below, for callers that want a
container parser, a resource policy, or accessor-level geometry without a scene
model on top.
draco-texture (KTX2 and Basis Universal transcoding) and the web/ WASM
wrappers are part of the repository but not published to crates.io; the wrappers
ship as assets on each draco-io and draco-gltf release.
[dependencies]
draco-gltf = "0.2"Read a primitive, whether or not it arrived Draco-compressed:
use draco_gltf::{MeshIndex, PrimitiveIndex};
let scene = draco_gltf::import("model.glb")?;
let geometry = scene.read_primitive(PrimitiveIndex::new(MeshIndex(0), 0))?;
println!("{} vertices", geometry.vertex_count());
# Ok::<(), draco_gltf::Error>(())Or stay at the format layer and convert geometry between files:
[dependencies]
draco-io = { version = "0.3", default-features = false, features = ["ply-reader", "obj-writer"] }Every crate is feature-gated down to what an application actually calls, which
matters most on wasm32: the format readers, the writers, the codec halves and
the strict-validation passes are all separable. Each crate's README lists its
features and what they cost.
draco-core is at 1.0 and its public API is covered by SemVer. Point clouds,
sequential meshes and both EdgeBreaker traversals encode and decode; the
per-algorithm matrix lives in
crates/draco-core/SUPPORT_MATRIX.md.
draco-io and draco-gltf are pre-1.0 and still move: a breaking change bumps
the minor, which is the breaking field for a 0.x crate. Each crate keeps its
own changelog and its own release tags — see CHANGELOG.md.
Beyond KHR_draco_mesh_compression, glTF reading covers EXT_meshopt_compression,
and Draco compression preserves the extensions a document carries rather than
refusing the file — including feature IDs, GPU instancing and structural
metadata.
Decoders here are assumed to be pointed at untrusted bytes. Malformed input must fail as a typed error rather than panic, hang, or allocate without bound, and decode limits are the caller's to set.
SECURITY.md— threat model, what is guaranteed, and the resource limits a caller should enforce.FUZZING.md— how the decode paths are fuzzed. Targets cover.drcdecode, glTF import and compression, FBX read and round-trip, and KTX2 transcode; they run per push and through ClusterFuzzLite.
./build.ps1 -Serve # from web/, builds the WASM modules and serves the appcd web && npm ci && bash ./build.sh --appbuild.sh defaults to the lightweight release profile that the size budget is
measured against; --app is the converter profile, which the front-end needs.
The web workspace guide covers the module features, the
TypeScript build, and the Node and Playwright suites.
| Path | Contents |
|---|---|
crates/ |
The published crates, plus draco-texture and the C++ test bridge. |
web/ |
WASM wrappers, the converter front-end, and its Node and Playwright suites. |
fuzz/, .clusterfuzzlite/ |
Fuzz targets and the continuous fuzzing setup. |
testdata/, dev/, tools/ |
Fixtures and development tooling. |
Apache-2.0. See LICENSE.