What Is STL?
STL — originally STereoLithography, now also interpreted as Standard Triangle Language or Standard Tessellation Language — is the oldest and most universal format for 3D printing. Created by Chuck Hull of 3D Systems in 1987 alongside the first stereolithography apparatus, STL describes 3D surfaces as a mesh of triangular facets. Despite its age and numerous limitations, STL remains the dominant format for FDM, SLA, SLS, and virtually every consumer 3D printer slicer.
STL's enduring success comes from one key property: simplicity. It stores only triangles — no texture, no color, no material, no hierarchy, no animation. Every slicer, CAD tool, and 3D modeling application can read and write STL.
STL File Structure
STL comes in two variants: ASCII and Binary.
ASCII STL
solid cube
facet normal 0 0 -1
outer loop
vertex 0 0 0
vertex 1 0 0
vertex 1 1 0
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 0 0 0
vertex 1 1 0
vertex 0 1 0
endloop
endfacet
...
endsolid cube
Each facet defines one triangle with:
- A normal vector (unit vector pointing outward from the surface)
- Three vertices in counterclockwise order when viewed from outside (right-hand rule)
Binary STL
Binary STL is far more compact — 80 bytes fixed header, then 4-byte triangle count, then per-triangle records of 50 bytes each:
Bytes 0-79: Header (usually ASCII text, not null-terminated)
Bytes 80-83: Number of triangles (uint32, little-endian)
For each triangle:
Bytes 0-11: Normal vector (3 × float32)
Bytes 12-23: Vertex 1 (3 × float32)
Bytes 24-35: Vertex 2 (3 × float32)
Bytes 36-47: Vertex 3 (3 × float32)
Bytes 48-49: Attribute byte count (uint16, usually 0)
Binary STL is approximately 5× smaller than ASCII STL for the same mesh. Almost all software generates binary by default.
Binary vs. ASCII detection: if the file starts with solid it might be ASCII — but many binary STL files also start with solid in their header. The correct detection method is to read the triangle count from bytes 80-83, compute the expected file size (84 + count × 50), and compare to actual file size.
The Normal Vector and Winding Order
The winding order (counterclockwise from outside) determines which side of a triangle is the "outside" (facing outward). The normal vector is redundant — it can be computed from vertices using the cross product — but STL includes it for software that does not perform this calculation.
Problems arise when:
- Normals point inward on some facets (inverted normals)
- Triangle winding is inconsistent (non-manifold edges)
- Triangles overlap or leave gaps (mesh errors)
Most 3D printing slicers attempt to repair these automatically.
Mesh Quality and Common Problems
| Problem | Cause | Fix |
|---|---|---|
| Non-manifold edges | Edge shared by more/fewer than 2 triangles | Repair with Meshmixer, Netfabb, or manifold library |
| Inverted normals | Inconsistent winding order | Recalculate normals in Blender or MeshLab |
| Holes in mesh | Missing triangles | Fill holes in Meshmixer, MeshLab, or manifold |
| Self-intersections | Triangles penetrating each other | Boolean union in OpenSCAD or Blender |
| Duplicate vertices | Disconnected triangles | Merge by distance in Blender |
| Degenerate triangles | Zero-area triangles | Cleanup in MeshLab |
Tools for repair:
- Meshmixer: free, GUI-based, excellent automatic repair
- MeshLab: free, open-source, powerful mesh processing pipeline
- Netfabb (now Microsoft 3D Builder): online and desktop repair
- PrusaSlicer / Cura: auto-repair during slicing
- OpenSCAD: programmatic CSG (Constructive Solid Geometry) for watertight models
STL Units: The Unitless Format
STL has no units. A coordinate of 25.4 could mean 25.4 mm, 25.4 inches, 25.4 cm, or anything else. The unit interpretation is agreed upon by convention between the modeling software and the slicer:
- Most CAD software (Fusion 360, SolidWorks) uses millimeters by default.
- Some older tools (AutoCAD) default to inches.
- Slicer software (Cura, PrusaSlicer) typically assumes millimeters.
When a print is 25.4× too large or small, it is usually a mm/inch mismatch — scale by 25.4 or 1/25.4.
3D Printing Workflow with STL
[CAD / 3D Model] → Export as STL
→ [Slicer: Cura / PrusaSlicer / ChituBox]
→ Configure: layer height, infill %, supports, orientation
→ Slice → Generate G-code / .ctb / .photon
→ Send to printer
→ Print
Key slicer settings affecting print quality:
- Layer height: 0.1–0.3 mm for FDM; 0.025–0.1 mm for SLA
- Infill: 15–20% for decorative; 40–60% for functional; 80–100% for structural
- Supports: tree or normal, based on overhang angle (typically > 45°)
- Orientation: minimize supports, maximize bed adhesion, consider layer strength direction
- Wall count / perimeters: 2–4 walls for strength
STL Limitations
STL cannot represent:
- Color or texture: use AMF or 3MF instead
- Multiple materials: no material regions
- Metadata: no author, creation date, or part properties
- Curved surfaces: only triangle approximations (more triangles = smoother surface but larger file)
- Units: agreed by convention only
- Assembly: one solid per file (by convention, though multiple
solidblocks are allowed)
Modern Alternatives
3MF (3D Manufacturing Format): XML-based, supports color, materials, textures, multiple parts, metadata, and print settings. Developed by the 3MF Consortium (Microsoft, Autodesk, HP, etc.). Becoming the preferred format for professional FDM printing.
AMF (Additive Manufacturing Format): XML-based alternative with similar features, less adoption than 3MF.
OBJ: supports textures and materials (via .mtl file), widely used in 3D art workflows.
STEP / IGES: parametric CAD exchange formats, used for engineering manufacturing.
Mesh Resolution Trade-offs
Triangle count controls quality vs. file size:
| Triangle count | Typical file size | Surface quality |
|---|---|---|
| < 10,000 | < 500 KB | Rough, low-poly |
| 10,000–100,000 | 500 KB–5 MB | Good for most prints |
| 100,000–1,000,000 | 5–50 MB | Very smooth |
| > 1,000,000 | > 50 MB | Excessive for printing |
Most slicers cannot effectively use more than ~1M triangles. For visual renders, higher counts are useful.
Programming with STL
Python:
import numpy as np
from stl import mesh # numpy-stl
# Load STL
model = mesh.Mesh.from_file('model.stl')
print(f"Triangles: {len(model.vectors)}")
print(f"Volume: {model.get_mass_properties()[0]:.2f} mm³")
# Create a simple cube
vertices = np.array([[0,0,0], [1,0,0], [1,1,0], [0,1,0],
[0,0,1], [1,0,1], [1,1,1], [0,1,1]])
faces = np.array([[0,3,1], [1,3,2], [0,4,7], [0,7,3],
[4,5,6], [4,6,7], [5,1,2], [5,2,6],
[2,3,7], [2,7,6], [0,1,5], [0,5,4]])
cube = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype))
for i, face in enumerate(faces):
for j in range(3):
cube.vectors[i][j] = vertices[face[j]]
cube.save('cube.stl')
Converting STL
- STL → OBJ: Blender, MeshLab, FreeCAD.
- STL → 3MF: Cura, PrusaSlicer, or Windows 3D Builder.
- STL → STEP/IGES: FreeCAD (Part → Convert to Solid → Export), or Autodesk Fusion 360.
- STL → PNG (render): Blender import + render, or PrusaSlicer preview screenshot.
- OBJ/FBX → STL: Blender (File → Export → STL).
- SCAD → STL: OpenSCAD compilation (F6).
Best Practices
- Use binary STL — 5× smaller than ASCII, universally supported.
- Design in millimeters — agree with slicer on mm to avoid scale errors.
- Ensure watertight mesh — no holes, no non-manifold edges before exporting.
- Keep triangle count reasonable: 50K–500K for typical FDM prints.
- Orient model correctly before exporting to minimize post-processing.
- Run Meshmixer Auto-Repair before slicing complex models.
- Use 3MF instead of STL when sending to professional print services — preserves print settings.
- Save original CAD file alongside STL for future modification.
- Check bounding box in slicer to verify scale before printing.
- For multi-material prints, use 3MF or separate STL files per material.
Related conversions
Frequent conversions across the catalogue: