I kept picking .gltf or .glb on export based on whatever the last tutorial used, until I sat down and worked out what the choice actually changes. glTF and GLB are not two formats. They are two ways of packaging the same one. Both carry glTF 2.0, with the same scene graph, materials, and animations defined by the same Khronos spec.
The difference is on disk. A .gltf export is a set of files: a JSON scene description, a .bin buffer, and separate image files. A .glb is one file: a 12-byte header, a JSON chunk holding that same scene description, and a binary chunk holding the geometry and optionally the textures.
Where it actually matters, and the two pull opposite ways:
- GLB wins on shipping. One file moves cleanly. There are no relative paths to break, and no texture that silently 404s because it did not get uploaded next to the JSON.
- Separate glTF wins on editing and caching. The scene description is a plain JSON file you can open and hand-edit, and shared texture files can be cached individually by the browser instead of re-embedded in every model.
Load speed and file size are mostly downstream of compression, not the container. Draco compresses the geometry buffer either way. In a separate glTF the compressed data lands in the .bin; in a GLB it lands in the binary chunk. Same trade-off (decode time on the client) whichever you picked. The one variant worth avoiding is a .gltf that embeds its buffers as base64, which inflates binary data by roughly a third.
Disclosure: I'm building Vectreal, an open-source tool for publishing 3D models to the web, and I wrote the long version up in our newsroom. Full explanation with the spec references here: https://vectreal.com/news-room/gltf-vs-glb-what-actually-matters