The Short Answer
If you want a single recommendation: use GLB. It is a single binary file that supports PBR materials and textures, loads fast, and works in every major web 3D library. But the full picture is more nuanced, and understanding why GLB wins helps you make better decisions when the choice is not so straightforward.
STL: Built for 3D Printing, Not the Web
STL (Stereolithography) is the dominant format in 3D printing, and many people encounter it first when downloading models from Thingiverse or Printables. An STL file stores a mesh as a list of triangles, with each triangle defined by three vertex positions and a face normal. That is all it stores. There are no materials, no colors in the standard binary format, no texture coordinates, and no scene hierarchy.
For web viewing, STL has significant drawbacks. Because there is no material or color information, every STL file renders as a monochrome surface. The format stores each triangle independently, meaning shared vertices are duplicated, which inflates file size by roughly two to three times compared to an indexed format. There is no built-in compression scheme. A moderately detailed STL file can easily reach 50 to 100 MB, which is unacceptable for web delivery where every megabyte adds seconds to load time on mobile connections.
That said, STL files are extremely common, and many web viewers support them precisely because users have STL files they need to preview. GeometryViewer loads STL files without any issue. But if you control the pipeline and are choosing a format specifically for web delivery, STL should be your last choice among the four options discussed here.
OBJ: Simple and Universal, but Inefficient
OBJ files are text-based and store geometry as indexed vertices, normals, texture coordinates, and polygon faces. Compared to STL, OBJ is more efficient because vertices can be shared across faces through indexing. Materials are defined in a separate MTL file, which supports basic diffuse color, specular highlights, ambient color, and texture map references.
For the web, OBJ has two main problems. First, it is entirely text-based, which means a 3D model that would be 5 MB as a binary file becomes 15 to 20 MB as OBJ plain text. Parsing text line by line is also significantly slower than reading structured binary data. Second, its material system predates physically based rendering, so models exported as OBJ often look different across viewers because each viewer interprets the limited MTL material properties in its own way.
OBJ also requires multiple files: the .obj geometry file, the .mtl material definition, and any referenced texture images. On the web, each file requires a separate HTTP request, adding latency. Some loaders handle this gracefully by resolving relative paths, but it adds complexity compared to a single-file format. If a texture file path is wrong or the MTL file is missing, the model loads without materials and the user sees a gray blob.
OBJ remains useful when you are dealing with legacy content or tools that do not support GLTF. It is also helpful for debugging because you can open the file in any text editor and inspect the raw geometry data. But for production web delivery, there are better options available today.
GLTF: The Modern Standard
GLTF (GL Transmission Format) was created by the Khronos Group specifically for efficient delivery of 3D content to web and mobile applications. A GLTF asset uses a JSON file for structure and metadata, paired with one or more binary buffer files (.bin) containing the actual vertex data, and separate texture image files. The material system is based on the metallic-roughness PBR model, the same shading model used by Unreal Engine, Unity, Blender, and virtually every modern rendering engine built in the last decade.
GLTF supports everything you need for rich 3D content on the web: multiple meshes organized in a scene graph, PBR materials with normal maps and ambient occlusion, skeletal animations, morph targets for blend shapes, cameras, and lights. The extension system allows optional features like clearcoat materials for car paint effects, transmission for glass, mesh quantization for compact storage, and Draco geometry compression that can shrink mesh data by 80 to 95 percent.
The multi-file nature of GLTF (a JSON descriptor plus binary data plus textures as separate files) is convenient during development when you might want to inspect or hand-edit the JSON. But for production deployment, you almost always want to package everything into a single GLB container file.
GLB: GLTF in a Single File
GLB is the binary container format for GLTF. It packages the JSON descriptor, all binary geometry buffers, and all texture images into a single file with a .glb extension. The internal structure is simple: a 12-byte header identifying the file version and total length, followed by a JSON chunk containing the scene description, followed by a binary chunk containing all the raw data. That is the entire specification.
For web delivery, GLB is the clear winner among all four formats:
- Single HTTP request. One file means one network fetch. No worrying about relative paths to textures, missing MTL sidecar files, or CORS issues with external resources.
- Binary efficiency. Vertex data is stored in compact binary, not verbose ASCII text. A model that weighs 20 MB as OBJ might be only 5 MB as GLB.
- PBR materials. Models look consistent across different viewers and engines because the material model is standardized and precisely defined by the Khronos specification.
- Draco compression. With the KHR_draco_mesh_compression extension, geometry data can be compressed by 80 to 95 percent, bringing a 5 MB file down to 500 KB or less.
- Universal library support. Three.js, Babylon.js, PlayCanvas, Google model-viewer, A-Frame, React Three Fiber, and every other major web 3D library treats GLB as its primary import format.
- Fast GPU upload. Binary buffer data can be transferred directly to GPU memory with minimal CPU-side processing, enabling near-instant display after download completes.
File Size Comparison
To put concrete numbers on the differences, consider a typical 100,000-triangle model with one 2048x2048 diffuse texture. Here are the approximate file sizes you can expect across each format:
- STL (binary): approximately 4.9 MB for geometry alone, with no texture support at all
- OBJ + MTL + texture: approximately 6.2 MB of text-encoded geometry plus 1.5 MB JPEG texture, totaling around 7.7 MB across three separate files
- GLTF + bin + texture: approximately 2.1 MB binary geometry plus 1.5 MB JPEG texture, totaling around 3.6 MB across multiple files
- GLB (uncompressed): approximately 3.6 MB in a single self-contained file
- GLB with Draco: approximately 1.8 MB total, with compressed geometry and embedded texture
The difference becomes more dramatic with larger models. A 1-million-triangle architectural model with multiple textures can easily reach 80 MB as OBJ but compress to under 10 MB as a Draco-compressed GLB. On a mobile connection averaging 5 Mbps, that is the difference between a 2-second load and a 2-minute wait.
Loading Speed and Browser Performance
File size directly affects download time, but parse time also matters significantly. On a mid-range smartphone, parsing a 20 MB OBJ file can take 3 to 5 seconds of JavaScript execution, during which the browser tab is completely unresponsive and the user sees nothing. The same model as a 5 MB GLB parses in under 500 milliseconds because the binary buffers require minimal processing before upload to the GPU.
Draco-compressed GLB files do add a decompression step, typically 100 to 300 ms on desktop and 500 to 800 ms on mobile devices. But this overhead is more than offset by the dramatically reduced download time, especially on cellular networks where bandwidth is limited and latency is high. The math almost always favors Draco for models larger than a few hundred kilobytes.
For the best user experience, aim for GLB files under 5 MB for mobile audiences and under 20 MB for desktop. Use KTX2 texture compression via the KHR_texture_basisu extension to reduce GPU texture memory without sacrificing visible quality. This is especially important on mobile devices where GPU memory is shared with system RAM.
CDN Delivery Tips
Once you have chosen GLB as your format, optimizing delivery through a CDN can further reduce perceived load times. Set long cache expiration headers, as 3D model files rarely change once published. A cache lifetime of one year is appropriate for versioned asset URLs. Enable Brotli compression at the HTTP transport layer. While GLB is binary, Brotli can still shave off 10 to 20 percent because the JSON chunk and certain repetitive patterns in buffer data are compressible.
Serve your files from CDN edge locations close to your users. If your audience is global, a CDN with points of presence in major regions ensures that a user in Tokyo is not fetching a model from a server in Virginia. Consider lazy loading: do not start the 3D model download until the viewer element is scrolled into the viewport. The Intersection Observer API makes this straightforward to implement, and it prevents wasting bandwidth on models the user may never scroll down to see.
Try It With Your Own Files
Drag and drop any STL, OBJ, GLTF, or GLB file into GeometryViewer to see it instantly. Compare how different formats look and load in your browser.
Open ViewerThe Decision Tree
Here is a simple framework for choosing. If your model needs animations or skeletal rigs, use GLB. If your model uses PBR materials with metalness, roughness, and normal maps, use GLB. If you need the smallest possible file for mobile delivery, use GLB with Draco compression. If you want to embed a 3D model on a webpage with a single HTML element using Google model-viewer, use GLB. If you are working with a legacy system that only accepts OBJ, use OBJ. If you are sharing a file specifically for 3D printing, STL is acceptable since printers do not use materials anyway. For virtually every other web-facing use case, GLB is the right answer.