The high-performance, WebAssembly-powered mesh repair engine for the browser.
MeshRepair is a lightweight, headless port of VCGlib (Visualization and Computer Graphics Library) specialized for the automated repair and sanitization of STL files. Built with Emscripten, it brings the industrial-grade mesh processing power of MeshLab directly into web-based 3D printing slicers, viewers, and CAD tools.
- Fast: Native-speed mesh processing via WebAssembly
- Complete: Full suite of mesh repair operations from VCGlib
- Simple: Clean TypeScript API with presets for common use cases
- Flexible: Works in browsers and Node.js
- Lightweight: No external dependencies, ~200-400KB WASM
npm install @goodtools/meshrepairimport { MeshRepair } from '@goodtools/meshrepair';
import loadMeshRepair from '@goodtools/meshrepair/wasm';
// Initialize
const meshrepair = await MeshRepair.init(loadMeshRepair);
// Load and repair an STL file
const stlData = await fetch('/model.stl').then((r) => r.arrayBuffer());
const { result, output } = meshrepair.repair('model.stl', new Uint8Array(stlData), 'print-ready');
console.log(`Repaired: ${result.originalFaces} -> ${result.finalFaces} faces`);
console.log(`Holes filled: ${result.holesFilled}`);
// Download repaired file
const blob = new Blob([output], { type: 'application/octet-stream' });
const url = URL.createObjectURL(blob);MeshRepair includes three presets for common use cases:
// Minimal - just remove duplicates and degenerate geometry
const { result } = meshrepair.repair('model.stl', data, 'minimal');
// Print-ready - fill holes, fix normals (recommended for 3D printing)
const { result } = meshrepair.repair('model.stl', data, 'print-ready');
// Aggressive - all repairs enabled
const { result } = meshrepair.repair('model.stl', data, 'aggressive');import { MeshRepair, PRESETS } from '@goodtools/meshrepair';
const { result, output } = meshrepair.repair('model.stl', data, {
// Start from a preset
...PRESETS['print-ready'],
// Customize options
maxHoleSize: 50, // Only fill holes with <=50 edges
removeNonManifoldFace: true,
removeNonManifoldVertex: true,
});const { result, output } = meshrepair.repair('model.stl', data, 'print-ready', (step, progress) => {
console.log(`${step}: ${(progress * 100).toFixed(0)}%`);
});For large files, write directly to the virtual filesystem to avoid extra memory copies:
const meshrepair = await MeshRepair.init(loadMeshRepair);
// Write large file directly to virtual FS
meshrepair.FS.writeFile('/uploads/huge-model.stl', hugeBuffer);
// Repair by path (memory efficient)
const { result, outputPath } = meshrepair.repairFileInPlace('/uploads/huge-model.stl', {
options: 'print-ready',
onProgress: (step, p) => updateProgressBar(step, p),
});
// Read output when ready
const repairedData = meshrepair.FS.readFile(outputPath);const meshrepair = await MeshRepair.init(loadMeshRepair, {
locateFile: (path, prefix) => {
if (path.endsWith('.wasm')) return '/assets/meshrepair.wasm';
return prefix + path;
},
});Initialize the MeshRepair WASM module.
Parameters:
loader: MeshRepairLoader- Function that loads the WASM module (import from@goodtools/meshrepair/wasm)options?: InitOptions- Optional initialization optionslocateFile?: (path: string, prefix: string) => string- Custom function to locate WASM files
Returns: Promise<MeshRepair>
Repair an STL file by passing data directly.
Parameters:
name: string- Filename (used for virtual FS path)data: string | ArrayBufferView- STL file dataoptions?: RepairOptions | PresetName- Repair options or preset nameonProgress?: (step: string, progress: number) => void- Progress callback
Returns: { result: RepairResult, output: Uint8Array }
Repair an STL file from a path in the virtual filesystem.
Repair without reading output back to JavaScript (memory efficient).
Direct access to Emscripten virtual filesystem for large file handling.
Clean up resources.
| Option | Type | Default | Description |
|---|---|---|---|
removeDuplicateVertex |
boolean | true | Remove vertices at the same position |
removeDuplicateFace |
boolean | true | Remove faces with identical vertex references |
removeUnreferencedVertex |
boolean | true | Remove vertices not referenced by any face |
removeDegenerateFace |
boolean | true | Remove faces with zero area |
fillHoles |
boolean | false | Fill holes in the mesh |
maxHoleSize |
number | 100 | Maximum hole size to fill (edge count) |
removeNonManifoldFace |
boolean | false | Remove non-manifold faces |
removeNonManifoldVertex |
boolean | false | Remove non-manifold vertices |
fixNormalOrientation |
boolean | false | Make face orientations consistent |
flipNormalsOutside |
boolean | false | Orient normals to point outward |
removeTVertexByFlip |
boolean | false | Remove T-vertices by edge flipping |
removeFaceFoldByFlip |
boolean | false | Remove face folds by edge flipping |
binaryOutput |
boolean | true | Output binary STL (false for ASCII) |
interface RepairResult {
code: number; // 0 = success
error?: string; // Error message if failed
originalVertices: number; // Vertices before repair
originalFaces: number; // Faces before repair
finalVertices: number; // Vertices after repair
finalFaces: number; // Faces after repair
duplicateVerticesRemoved: number;
duplicateFacesRemoved: number;
unreferencedVerticesRemoved: number;
degenerateFacesRemoved: number;
nonManifoldFacesRemoved: number;
nonManifoldVerticesRemoved: number;
holesFilled: number;
}- Docker
- Node.js 22+
# Build the Docker image with Emscripten
npm run build:builder
# Build the WASM library
npm run build:emscripten
# Build the TypeScript wrapper
npm install
npm run buildRequires Emscripten SDK, Meson, and Ninja installed locally.
npm run build:emscripten-local
npm run buildThis project uses Changesets for version management and changelog generation.
When making changes that should be included in the next release:
npm run changesetSelect the package, choose the change type (major/minor/patch), and write a summary. This creates a changeset file that will be included in the next release.
- major: Breaking changes (e.g., API changes, renamed exports)
- minor: New features (backward compatible)
- patch: Bug fixes
MeshRepair is licensed under the GNU General Public License v3.0, the same license as VCGlib.
VCGlib is developed by the Visual Computing Lab at ISTI-CNR.
- VCGlib - The underlying mesh processing library
- MeshLab - VCGlib's flagship application
- Emscripten - C++ to WebAssembly compiler
- Wiregasm - Architectural inspiration