Convert STL to OBJ

Converting STL to OBJ gives a modelling application a mesh it can work with rather than a bag of loose triangles. The important part happens on the way in: an STL shares no vertices between triangles, and welding them is what makes edge selection, subdivision and smooth shading behave in Blender, ZBrush or Maya.

  • Where it runs In your browser. The file is never uploaded.
  • Rebuilt OBJ works differently from an STL, so this is not the gradual degradation a lossy codec applies. What OBJ can express is reproduced faithfully; what it has no equivalent for does not survive at all.
  • File size limit Up to 100 MB per file, free, without an account.
  • Worth knowing Geometry only. Materials, colours, textures and animation are not carried across, and a model placed several times comes back with each copy baked into its own position.

Up to 100 files at once. Mixed formats are fine.

Getting an STL out of the printing world so you can change it

STL exists to be sliced. It carries triangles and nothing else, which is precisely what a slicer wants and precisely what a modelling application does not — no groups to isolate, no materials to assign, no names to search, and, crucially, no shared vertices. Everything a modeller does begins with selecting part of a mesh, and an STL gives them nothing to select.

OBJ is the opposite kind of file: text, indexed, grouped, universally imported, and old enough that even a package from 1998 reads it. It is not a better format than STL in the abstract; it is the format that every tool in a modelling pipeline treats as the default, which is exactly what you want when the next step is somebody else’s software.

Welding is what makes the mesh selectable at all

A cube in an STL is twelve triangles with thirty-six vertices, because each triangle carries its three corners independently and the eight actual corners are written four or five times each. Import that unchanged and every triangle is its own island: Select Linked picks one face, loop select finds no loop, subdivision produces gaps, and smooth shading has no shared normals to average, so the surface stays faceted whatever you set.

The reader here merges coincident vertices before anything is written. The comparison key is rounded to six decimal places, because two triangles meeting at an edge routinely disagree in the last bit of a float — six places is far below any printable tolerance and far above the noise. The cube comes out with eight vertices and twelve faces, which is a mesh in the sense a modeller means it: connected, loop-selectable, subdividable, and shadeable smooth.

What the OBJ file actually contains

A comment line, one `o` line naming the single group, then a `v` line per vertex and an `f` line per triangle. That is the whole file. Indices are one-based, as OBJ requires, and count across the file rather than per group.

There are no `vt` lines because an STL has no texture coordinates, no `vn` lines because the normals are derivable, no `usemtl` line because there is no material, and no `mtllib` reference because there is no material library. Anything that opens OBJ will read it; there is nothing unusual in the file for an importer to disagree about.

The single group, and separating the parts afterwards

An STL has no concept of an object, so the OBJ has one group and it is named `mesh_1`. A model that was assembled from a body, a lid and a handle arrives as one group containing three disconnected shells.

Every modelling application can split that. Blender does it with Separate By Loose Parts in edit mode; MeshLab has Split in Connected Components; Maya and 3ds Max both have an equivalent. What none of them can do is recover the names, because the STL never had them. If the names matter and you have any choice about the source file, 3MF and OBJ both keep them and STL never will.

No normals are written, and that is the right decision

An STL stores a face normal per triangle. It is not written into the OBJ, and nothing is lost: a face normal is fully determined by the winding order of its three corners, and every application recomputes it on import. Several slicers ignore the stored value entirely, precisely because so many writers get it wrong.

The absence of vertex normals is more interesting. Without them the importer computes its own, which for a welded mesh means averaging across the shared vertices — so the model arrives ready to be shaded smooth or flat as you choose, with the choice living in your application rather than baked into the file. On a converted CAD export, adding an edge-split or sharp-edge threshold gives you the crisp chamfers and smooth cylinders in one step.

How the reader decides whether your STL is binary or text

Both dialects convert and the file does not say which it is. The usual test — does the file begin with the word `solid`? — is wrong, because a binary STL is allowed anything in its eighty-byte header and several writers put `solid` there, which produces a file that looks like text and is not.

The reliable test is arithmetic: a binary STL is exactly 84 + 50n bytes for the triangle count declared in its header, and nothing else is. That is what is checked. If the arithmetic does not hold, the file is decoded as text and every `vertex` line is read. A file that is neither — truncated, or an STL in name only — stops with a message rather than producing an empty mesh.

The size of the OBJ against the STL it came from

Two effects pull in opposite directions. Welding removes most of the duplication: a typical mesh has each vertex shared by five or six triangles, so the vertex list shrinks by roughly that factor. Text expands what is left: a four-byte float becomes ten to fifteen characters of decimal, and the face lines add their own.

The result is usually in the same range with the OBJ somewhat ahead of the binary STL — an increase rather than a multiplication. The free ceiling here is 100 MB, which is around two million STL triangles, and a mesh that dense is beyond what most modelling sessions want anyway. If the STL is very large, decimating before converting is faster than decimating after.

Importing the converted OBJ into Blender or MeshLab

Two settings are worth checking on the way in. The up axis: OBJ has no convention and Blender’s importer defaults to Y-up, while an STL from a CAD or printing workflow is almost always Z-up, so the model arrives lying on its face unless you set it. And the scale: neither format declares a unit, and if the STL was in millimetres then a Blender scene in metres will treat a 60 mm part as sixty metres.

After import, the first useful move on any converted CAD mesh is Merge By Distance with a very small threshold, which catches anything the six-decimal welding did not because the source geometry genuinely disagreed. Then look at the statistics: if the vertex count is close to three times the face count, the welding did not take and something about the source is unusual.

Triangles all the way down, and what that means for editing

The mesh is welded and it is still entirely triangles, because that is all the STL ever held. Quads and n-gons cannot be recovered — the information about which triangle pairs were once a quad is not in the file and cannot be inferred reliably. Sculpting, boolean operations, decimation and measurement all work fine on triangles.

What does not work well is subdivision surface modelling and any workflow that relies on clean edge flow, both of which want quads. If you are going to keep working on this model rather than making one change to it, retopology is the honest next step: Blender’s Quadriflow Remesh, ZBrush’s ZRemesher or InstantMeshes will give you a quad mesh in one pass, and the converted OBJ is a perfectly good input to any of them.

Where the STL is converted

In this browser tab, by plain JavaScript. No WebAssembly module is downloaded, nothing is uploaded, there is no account and no daily allowance. Opening the network tab and converting something is how to confirm it.

STLs are frequently somebody else’s design — a client’s part, a supplier’s geometry, a component under an agreement — and the modelling job on this page is exactly the situation where that is true. A conversion that never sends the file avoids the question rather than answering it.

How to turn an STL into an editable OBJ mesh

  1. Drop the STL onto this page, or click to choose one.
  2. Coincident vertices are welded and the mesh written as OBJ, in your browser.
  3. Import with the up axis set to Z, then separate the loose parts if there are several.

STL and OBJ: unshared triangles against an indexed mesh

STL compared with OBJ
STLOBJ
Full nameStereolithographyWavefront Object
File extension.stl.obj
Media typemodel/stlmodel/obj
First published19871992
Published by3D SystemsWavefront Technologies
LicensingOpen standardOpen standard
Standing todayCurrentCurrent
Opens in a browserNo browserNo browser
Considered instead3MF, PLYGLTF, PLY

Opening the result

Blender reads both STL and OBJ, so there is a way to check the result against the original without a second tool.

What each format is for

The two are aimed at different work: STL at 3D printing, OBJ at moving data between programs and editing. That is worth weighing before converting, because the reason one exists is usually the reason the other is awkward.

OBJ comes from Wavefront Technologies and dates from 1992. Blender, MeshLab and Maya all read it.

STL to OBJ: welding, groups and materials

Are my STL files uploaded anywhere?

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.

Why can I not select linked geometry in an imported STL?

Because an STL stores every triangle as three independent vertices with no sharing, so nothing is topologically connected. This conversion welds coincident vertices on the way in, which is what restores edge loops, Select Linked, subdivision and smooth shading.

Does the OBJ keep any part names?

There is nothing to keep. An STL has no object or group structure at all, so the OBJ arrives as a single group. Separate the shells in your modelling application afterwards if the model was really several parts.

Is there an MTL file?

No, and there is nothing to put in one. An STL carries no colour, material, texture or UV information, so the OBJ references no material library and your application will apply its default.

Are vertex normals written?

No. The file contains v and f lines only, so your application computes the normals from face winding on import. For a converted STL that is the right outcome — the stored normals were derivable anyway.

Why is the OBJ larger than the STL?

Because the coordinates become decimal text rather than four-byte floats. Welding removes most of the duplication and the text expansion adds it back, so the two usually land in the same range with the OBJ somewhat ahead.

Does it read both kinds of STL?

Yes. Binary and ASCII are both handled, and the file is identified by arithmetic rather than by looking for the word "solid" — several binary writers put that word in the header.

More about these formats