Library / SDK
google/draco avatar
google/draco

google/draco: Mesh and Point Cloud Compression for glTF Pipelines

Draco is a library for compressing and decompressing 3D geometric meshes and point clouds. It is intended to improve the storage and transmission of 3D graphics.

7,495 stars1,078 forksC++Apache-2.0

At a glance

What is it?
Draco is a C++ library that compresses 3D meshes and point clouds, with JavaScript and WASM decoders for the browser. It is the right tool when geometry payload size is the bottleneck, and the wrong one when you need lossless geometry or a decoder that ships everywhere without setup.
Who is it for?
Adopt Draco if you ship glTF assets over a network and can accept quantization, and if your client can load a WASM or JavaScript decoder or a native build. Do not adopt it if you need bit-exact geometry round-trips, or if you cannot control the decoder version your clients fetch.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Draco compresses, and who actually needs it

Draco targets 3D geometric meshes and point clouds, not textures, not animation curves, not audio. The repository description states the intent plainly: to improve the storage and transmission of 3D graphics. That narrow scope is the useful part. If your problem is a 200 MB glTF scene that takes too long to download, Draco is aimed at exactly that. If your problem is texture memory, it does nothing for you.

The audience is narrower than the topic list suggests. You need to be producing or consuming geometry in a pipeline you control: a glTF exporter, a viewer, a game engine plugin, a photogrammetry tool, or a point cloud viewer. The repository ships a maya/ directory and a unity/ directory, which tells you the project expects DCC and engine integration rather than pure server-side batch work. The javascript/ directory and the Emscripten build path show the other half of the intended audience: people who need to decode geometry in a browser tab without a plugin.

One thing the README makes clear is that this is not a drop-in file format you can hand to any consumer. The decoders are distributed as WASM and JavaScript from gstatic, and the release notes repeatedly tell you to pin to a versioned URL. That instruction only makes sense if you are the one writing the loader code.

The mechanism: quantization plus entropy coding, and the glTF transcoder

Draco is not a general-purpose archiver. It works on the structure of geometry. Vertex positions, normals, texture coordinates and other attributes are quantized to a fixed number of bits, then the connectivity and the quantized values are encoded with entropy coding. The release notes for 1.4.0 record a change to the default: the NORMAL quantization default became 8. That is a direct statement that the library is lossy by default for normals, and the bit count is the knob you turn.

Connectivity is handled separately from attributes. That separation is why Draco can compress a mesh far beyond what a generic compressor achieves on the same data, and also why the output is not a byte-for-byte representation of the input. The quantization step is where precision is lost, and it happens before encoding.

For glTF specifically, the project added draco_transcoder in the 1.5.0 release. This is a distinct tool from the encoder and decoder. It takes glTF and glTF binary input and produces Draco-compressed glTF, and the build and dependency instructions live in BUILDING.md. There is a CMake flag, DRACO_GLTF_BITSTREAM, renamed from DRACO_GLTF in 1.5.0, that limits the feature set to what the Draco glTF specification includes. If you are producing glTF, that flag is the line between the full codec and the interoperable subset.

Partial support for the glTF extensions EXT_mesh_features and EXT_structural_metadata arrived in 1.5.4. Partial is the word the release notes use, so if your assets carry those extensions, treat that support as incomplete until you check your own files.

Building Draco from source with CMake

The repository is a CMake project. CMakeLists.txt sits at the top level, with a cmake/ directory for modules, and BUILDING.md and CMAKE.md carry the build documentation. The third_party/ directory and a .gitmodules file indicate submodules, so a plain clone may not be enough to configure.

The build documentation in BUILDING.md is where the configure and build steps live. What you get depends on the options you pass. The release notes mention DRACO_GLTF_BITSTREAM for limiting features to the glTF specification, and DRACO_DEBUG_COMPILER_WARNINGS, which replaced DRACO_DEBUG_MSVC_WARNINGS in 1.5.6 and is now a boolean defined in draco_options.cmake rather than a flag with the old behaviour. If you are chasing compiler warnings, that rename is the first thing to check in an old build script.

For consuming Draco from another CMake project, 1.5.1 added draco-config.cmake, tested on Linux, macOS and Windows. The README points at the install_test subdirectory of src/draco/tools for an example. That is the path to follow if you want find_package to work rather than hand-wiring include and library paths.

One caveat worth stating: the 1.5.0 notes say the CMake install target changed to use absolute paths from CMake instead of CMAKE_INSTALL_PREFIX. For downstream packagers this was framed as a simplification, but it is a change in install behaviour and worth diffing against your packaging scripts.

Using the JavaScript decoder in a browser viewer

The browser path does not require you to build anything. The decoders are hosted, and the README is explicit that versioned URLs are recommended over the unversioned v1/decoders path. The stated reason is edge caching and gstatic propagation delays producing transient errors that are hard to diagnose when a new release lands. That is a real operational hazard: your site can break at the moment someone else publishes a release.

The URL pattern for the current release, from the 1.5.7 notes, is this:

bash
https://www.gstatic.com/draco/versioned/decoders/1.5.7/*

Replace the asterisk with the file you need, for example draco_decoder.js or draco_decoder_gltf.wasm. Pin the version in your loader rather than resolving it at runtime.

There is a second thing to know about the JavaScript API. The 1.4.0 release moved the npm modules to WASM and, because of the Emscripten 2.0 update, the codec modules now return a promise instead of the module directly. The README tells you to see the example code for handling that promise. If you are porting from an older integration, this is the breaking change that will bite first.

The same release deprecated DecoderBuffer in favour of a new array API. Both changes point at the same conclusion: the JavaScript surface has moved, and old tutorials you find online may not match the current modules.

Where Draco is the wrong choice

The clearest limitation is baked into the design: quantization is lossy, and it is the default. If your pipeline requires bit-exact geometry, for example a CAD interchange where a vertex moved by a fraction of a unit changes the meaning of the model, Draco's core mechanism works against you. You can raise the quantization bits, but you cannot make the encoder a lossless archiver by turning a knob.

The second limitation is decoder availability. A Draco-compressed glTF is not readable by a viewer that lacks the decoder. The project distributes WASM and JavaScript decoders from a static URL and builds native libraries, but that still means every consumer has to have one. If you are handing assets to third parties whose tooling you do not control, you are adding a dependency they may not have.

The third is version coupling on the web. The README's own warning about unversioned gstatic URLs is effectively a statement that decoder resolution can fail transiently. A team that treats the decoder URL as a fixed constant rather than a pinned version inherits that failure mode.

Finally, the release cadence is worth noting. The releases listed in the README are 1.5.5 from 2022-10-29, 1.5.6 from 2023-02-07, and 1.5.7 from 2024-01-17. The repository's last push was on 2026-08-18, so work continues on the main branch, but tagged releases are infrequent. If your adoption process requires a recent tagged release, plan around that gap.

Draco against meshoptimizer and glTFpack

The obvious comparison in the glTF world is meshoptimizer, whose glTFpack tool also compresses meshes for transmission. The difference in approach matters. Draco encodes connectivity and quantized attributes with its own entropy coder and produces a bitstream that requires the Draco decoder. glTFpack's compression path is built around the EXT_meshopt_compression glTF extension, which is decoded by a small routine rather than a full codec, and the extension is designed to be applied to buffer views inside a glTF file.

That changes the integration story. With EXT_meshopt_compression, the compressed data lives in a glTF extension and a conforming loader that implements the extension can decode it. With Draco, the geometry is in a Draco bitstream and the loader needs the Draco decoder, which is why the project ships WASM and JavaScript builds and why the glTF extension for Draco exists at all. Neither is universally better. The trade-off is codec strength and tooling maturity on one side, and decoder footprint and format integration on the other.

There is a second axis: what each tool does besides compression. Draco's repository includes a transcoder for glTF input and plugins for Maya and Unity. glTFpack is a command-line optimizer that also handles mesh simplification and vertex cache optimization. If you need one tool that does compression plus geometry cleanup, that difference is the deciding factor, not the compression ratio.

Licence and the cost of keeping up

Draco is licensed under Apache-2.0, with the LICENSE file at the repository root. Apache-2.0 is a permissive licence with an explicit patent grant, which is generally the reason projects in this space pick it over MIT. It is compatible with being bundled into proprietary applications, subject to the usual notice and attribution conditions. That is a description of the licence text, not legal advice; if you are redistributing Draco inside a product, have your own counsel read the NOTICE and attribution requirements rather than taking this paragraph as clearance.

The upgrade cost is concentrated in two places. First, the CMake configuration surface has moved more than once: DRACO_GLTF became DRACO_GLTF_BITSTREAM in 1.5.0, DRACO_DEBUG_MSVC_WARNINGS became DRACO_DEBUG_COMPILER_WARNINGS in 1.5.6 with changed behaviour, and the exported variables in draco-config.cmake and find-draco.cmake were renamed in 1.5.0. Each of those is a build-script edit.

Second, the JavaScript and WASM decoder behaviour changed at 1.4.0 with the promise-returning modules and the deprecated DecoderBuffer. If you pin a decoder version, upgrading means re-testing your loader, not just bumping a URL. The README's own advice to pin versions is also the reason upgrades are deliberate rather than automatic: you choose when to move.

Editorial conclusion

Adopt Draco if you ship glTF assets over a network and can accept quantization, and if your client can load a WASM or JavaScript decoder or a native build. Do not adopt it if you need bit-exact geometry round-trips, or if you cannot control the decoder version your clients fetch. Before committing, verify three things: whether your meshes survive the quantization defaults, whether your viewer already bundles a Draco decoder, and which versioned gstatic URL your build pins, since the README warns that unversioned URLs can return transient errors during a release.

Frequently asked questions

How do you install google/draco?

Draco is a CMake project, and BUILDING.md carries the build and dependency information. For use from another CMake project, draco-config.cmake was added in 1.5.1 and is tested on Linux, macOS and Windows.

How do you use google/draco in a browser?

The README recommends pulling the WASM and JavaScript decoders from a versioned gstatic URL, for example https://www.gstatic.com/draco/versioned/decoders/1.5.7/, replacing the asterisk with the file you need. Since 1.4.0 the codec modules return a promise rather than the module directly, and the README points to the example code for handling that.

Does google/draco compress losslessly?

No. Attributes are quantized before entropy coding, and the 1.4.0 release notes record that the default NORMAL quantization became 8. You can raise the bit count, but quantization is inherent to the mechanism.

What glTF tooling does google/draco provide?

The draco_transcoder tool was added in 1.5.0 and converts glTF and glTF binary input into Draco-compressed glTF. The DRACO_GLTF_BITSTREAM CMake flag limits features to those in the Draco glTF specification.

Why does the README warn against unversioned Draco decoder URLs?

The README states that edge caching and gstatic propagation delays can cause transient errors that are difficult to diagnose when new Draco releases launch, and recommends pinning sites to a versioned release to avoid the issue.

Official sources

  1. google/draco on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/google-draco.svg)](https://hysenlabs.com/projects/google-draco)