Cookies for analytics and advertising
We use cookies for analytics and advertising, both sent to Google. Refusing changes nothing you can see.Read the privacy page
Converting STL to GLB produces one binary file that a web viewer, a preview pane or an upload form will accept where an STL is refused. The geometry crosses cleanly; what surprises people is the presentation, because an STL brings no material and its Z-up orientation lands sideways in a viewer that expects Y-up.
Up to 100 files at once. Mixed formats are fine.
They convert one after another and download together as a ZIP.
STL to GLB
Three situations account for nearly all of this conversion. An upload field on a listing, a documentation platform or a content system that names `.glb` because that is what its viewer component loads. A colleague or client who needs to look at a part and has no slicer, no CAD package and no intention of installing either. And an augmented-reality or preview feature that was built around glTF because that is what the web standardised on.
In none of those cases is the person converting building a 3D application. They want a file the other end will open, showing the shape, this afternoon. That framing is worth holding, because most advice about glTF is written for people assembling scenes and answers questions this reader does not have.
A GLB is the same glTF document with its vertex data concatenated behind it: a twelve-byte header whose first four bytes spell `glTF`, then a JSON chunk, then a binary chunk, each padded out to a four-byte boundary. One file, one request, nothing beside it.
That matters against the alternative on this site. Converting an STL to `.gltf` produces a single file too, but it has to carry the vertex data as a base64 data URI inside the JSON, which costs four characters for every three bytes — about thirty-three per cent — with indented JSON on top. The GLB stores the same bytes directly, so it is meaningfully smaller for exactly the same geometry. If the file is going to be downloaded by anybody, this is the version to send.
An STL has no colour, no texture, no UV coordinates and no vertex colours, and the converter writes a primitive with a position accessor and an index accessor and no material reference at all. Whatever appears on screen is produced entirely by the viewer’s defaults.
That is why the same file can look like a solid engineered object in one viewer and a grey blob in another. The fix is lighting rather than conversion: `<model-viewer>` ships neutral environment lighting and a `shadow-intensity` attribute, and adding both is two attributes and transforms the result. In three.js an environment map plus a hemisphere light does the same job. If the part genuinely needs a colour, add a material to the glTF afterwards with `gltf-transform` — it is a small edit to a document that is otherwise complete.
This is the one that makes people think the conversion failed. CAD packages and the entire 3D printing world work Z-up: the build plate is the XY plane and height is Z. glTF specifies Y as up, and every viewer follows it. Nothing in the conversion rotates anything, because inventing a rotation would be guessing at which convention the source followed.
So a part exported from Fusion, SolidWorks, FreeCAD or a slicer arrives in the viewer tipped ninety degrees onto its back. Correct it in the scene rather than in the file: `<model-viewer>` takes an `orientation="-90deg 0 0"` attribute, and three.js needs one line setting `object.rotation.x`. Doing it in the viewer keeps the GLB matching the STL, which matters if the same geometry is also going to a printer.
Neither format declares a unit. STL is treated as millimetres by every slicer ever written; glTF is authored as though one unit is one metre. The numbers pass through untouched, so a 60 mm bracket becomes a sixty-unit object, which a viewer sized for metres renders as a sixty-metre bracket and frames from a long way away.
Divide by 1000 in the scene, and check against a dimension you can verify rather than by eye. `<model-viewer>` has a `scale` attribute; three.js has `object.scale.setScalar(0.001)`. If the viewer looks correct without scaling, the STL was probably not in millimetres, which is worth knowing before it goes to a printer.
An STL stores every triangle as three independent vertices with no sharing at all, so a cube arrives as thirty-six positions where eight would do. The reader merges coincident vertices first, comparing at six decimal places, because two triangles meeting at an edge routinely disagree in the last bit of a float.
For a delivery file that is not a nicety. The unwelded form would put four to six times as many vertices into the buffer and therefore into the download, and it would also break smooth shading, since a viewer averaging normals needs shared vertices to average across. The result is a GLB whose geometry is both smaller and better behaved than a naive rewrite would produce.
Everything found in the STL is written as a single mesh with a single primitive, because an STL has no groups to preserve. That is the cheapest possible model for a renderer — one draw call, no material switches — which is the right shape for a part on a product page or in a preview pane.
The primitive uses uint32 indices and float32 positions throughout. Narrower index types exist and would save a little on a small model, but a mesh crossing 65,535 vertices then silently needs a different type, which is a conditional that is easy to get wrong for a few kilobytes. The position accessor carries `min` and `max` as the specification requires, which is what lets a viewer frame the model on load instead of opening zoomed to nothing.
This is the quietly useful case. A colleague, a client or a customer needs to see a part and has no software for it — sending an STL means explaining what to install, and sending a screenshot means they cannot turn it round. A GLB opens in a browser-based viewer with no installation, and every current phone and desktop can render one through a page.
What to send with it: the real dimensions, in a sentence, because the file does not carry them and the viewer will show whatever scale you set. And a note about orientation if it matters. Two lines of context turn a grey object floating in a viewer into a part somebody can comment on.
Usually a good deal smaller. The STL is fifty bytes per triangle with no sharing; the GLB stores each vertex once as twelve bytes and each index as four, so a mesh whose vertices are each used by five or six triangles compresses substantially in the geometric sense before any compression is applied.
The free ceiling is 100 MB, which is about two million STL triangles. Well before that, a model becomes uncomfortable to load in a browser — a few hundred thousand triangles is a sensible upper bound for something a visitor will open on a phone. If the STL is denser than that, decimate before converting; `gltf-transform` can also apply Draco compression to the resulting GLB, though bear in mind that a Draco-compressed file cannot be converted back on this site.
Nothing does. The conversion is plain JavaScript in this tab, with no WebAssembly module to download, no upload, no account and no daily allowance. The network tab during a conversion is the check.
That is the relevant point for a part being prepared for a listing or a client review, because the model is frequently unreleased and frequently somebody else’s. A conversion that never transmits the geometry removes the question entirely rather than answering it with a privacy policy.
| STL | GLB | |
|---|---|---|
| Full name | Stereolithography | Binary glTF |
| File extension | .stl | .glb |
| Media type | model/stl | model/gltf-binary |
| First published | 1987 | 2016 |
| Published by | 3D Systems | Khronos Group |
| Specification | — | glTF 2.0 |
| Licensing | Open standard | Open standard |
| Standing today | Current | Current |
| Opens in a browser | No browser | No browser |
| Considered instead | 3MF, OBJ, PLY | GLTF, OBJ |
Blender reads both STL and GLB, so there is a way to check the result against the original without a second tool.
The two are aimed at different work: STL at 3D printing, GLB at the web and handing a finished file over. That is worth weighing before converting, because the reason one exists is usually the reason the other is awkward.
GLB comes from Khronos Group and dates from 2016, specified as glTF 2.0. Blender, three.js and Babylon.js all read it.
STL was published in 1987 and GLB in 2016. The older one is generally the safer file to hand to somebody; the newer one usually does the job in fewer bytes.
No. This conversion runs entirely inside your browser, so the file never leaves your device. You can confirm it yourself: open the network tab of your browser's developer tools and convert something. You will see the page load, plus the analytics and advertising the site is paid for with — and nothing carrying your file.
Because an STL has no colour, material or texture and there is nothing to write into the GLB. What the viewer shows is entirely down to its own lighting, so an environment map and a shadow do more for the result than any conversion setting could.
STL geometry from a CAD or printing workflow is almost always Z-up, and glTF viewers are Y-up. Nothing rotates it, so it arrives tipped ninety degrees. One orientation attribute in the viewer fixes it without touching the file.
Scale. An STL is conventionally millimetres and glTF conventionally metres, so a 60 mm part becomes sixty units — sixty metres — in a viewer that assumes the glTF convention. Divide by 1000 in the scene.
Yes, always. A GLB packs the JSON and the vertex buffer into one binary file, so there is no .bin sidecar to lose and no relative path to break when the file is moved or uploaded.
Yes, by roughly a quarter. The glTF conversion has to embed its buffer as base64, which costs about a third on top of the raw bytes, plus indented JSON around it. The GLB stores those same bytes directly.
No. The STL is read and the GLB assembled by JavaScript in this tab, with no engine download and no request carrying the file. Parts under an agreement stay on the machine.