How it works
Import-once plans, random-access byte IO, canonical formats, async resolution, and production Wasm flags.
One plan
The custom IOSystem exposes named in-memory byte arrays through Assimp's random-access Read, Seek, and Tell contract. It is not Emscripten MEMFS: there is no path mount, duplicate filesystem copy, or public filesystem lifetime. A generic stream cannot replace it because importers seek, probe, and reopen sidecars.
convertFormats validates the whole request, copies inputs once, imports and post-processes one scene, then exports targets sequentially into isolated output stores. A later failure destroys all native output state and rejects with positional context. Singular convert creates a one-target plan and unwraps the same result path.
Async resolution with one artifact
The package ships one baseline-compatible libassimp.wasm artifact:
The replay cache is per conversion and invokes the consumer resolver once per exact name. Each pending attempt stops host callbacks immediately, awaits newly discovered work, and reuses settled bytes on the next attempt. JSPI-capable Chromium suspends inside parsing instead. Both paths use the same final SHA and have exact output, resolver-trace, and error parity tests.
Each Assimp instance serializes singular and plural work through one rejection-safe FIFO queue. Separate instances are the parallelism boundary. dispose() rejects new calls and releases the runtime after queued work settles.
Canonical formats
Public targets are not Assimp exporter IDs. glb and gltf always route to glTF 2; dae and step are canonical names; FBX/PLY/STL encoding uses exportOptions.binary; OBJ sidecar behavior uses exportOptions.materials and defaults to materials.
| Target id | Writes |
|---|---|
3ds | result.3ds — Autodesk 3DS (legacy) |
3mf | result.3mf — 3D Manufacturing Format |
assjson | result.json — Assimp JSON scene |
dae | result.dae — COLLADA Digital Asset Exchange |
fbx | result.fbx — Autodesk FBX |
glb | result.glb — glTF 2 binary container |
gltf | result.gltf — glTF 2 JSON with sidecars |
obj | result.obj — Wavefront OBJ |
ply | result.ply — Stanford Polygon Library |
step | result.stp — ISO 10303 STEP |
stl | result.stl — Stereolithography |
usda | result.usda — Universal Scene Description ASCII |
usdz | result.usdz — Universal Scene Description ZIP container |
x | result.x — DirectX X file |
x3d | result.x3d — Extensible 3D |
The import table is directional: it lists readable extensions, not writable targets.
| Format | Extensions |
|---|---|
| 3D GameStudio Heightmap (HMP) | .hmp |
| 3mf | .3mf |
| AC3D | .ac .acc .ac3d |
| ASE | .ase .ask |
| Additive manufacturing file format(AMF) | .amf |
| Autodesk FBX | .fbx |
| BVH Importer (MoCap) | .bvh |
| Blender 3D Importer (http://www.blender3d.org) | .blend |
| BlitzBasic 3D | .b3d |
| CharacterStudio Motion Importer (MoCap) | .csm |
| Collada | .dae .xml .zae |
| Direct3D XFile | .x |
| Discreet 3DS | .3ds .prj |
| Doom 3 / MD5 Mesh | .md5mesh .md5camera .md5anim |
| Drawing Interchange Format (DXF) | .dxf |
| Industry Foundation Classes (IFC) Importer (Web-IFC) | .ifc |
| Inter-Quake Model | .iqm |
| LightWave Scene | .lws .mot |
| LightWave/Modo Object | .lwo .lxo |
| MMD | .pmx |
| Milkshape 3D | .ms3d |
| Nendo Mesh | .ndo |
| Neutral File Format | .enff .nff |
| OFF | .off |
| Ogre3D Mesh | .mesh .mesh.xml |
| Open Game Engine Exchange | .ogex |
| Quake II Mesh | .md2 |
| Quake III BSP | .bsp .pk3 |
| Quake III Mesh | .md3 |
| Quake Mesh / 3D GameStudio Mesh | .mdl |
| Quick3D | .q3o .q3s |
| Return To Castle Wolfenstein Mesh | .mdc |
| Silo SIB | .sib |
| Stanford Polygon Library (PLY) | .ply |
| Stereolithography (STL) | .stl |
| TrueSpace Object | .cob .scn |
| USD Object | .usd .usda .usdc .usdz |
| Unreal Mesh | .3d .uc |
| VRML(WRL, X3DV) and Extensible 3D(X3D, X3DB) | .wrl .x3d .x3db .x3dv |
| Valve SMD | .smd .vta |
| Wavefront Object | .obj |
| XGL | .xgl .zgl |
| glTF | .gltf .glb |
| glTF2 | .vrm |
assimpCapabilities, the instance formats tables, conversionEdges, TypeScript unions, validation, and these matrices come from one checked-in compiler-derived registry. Native names never enter the public catalog.
Post-processing
defaultPostProcess is Triangulate, GenUVCoords, JoinIdenticalVertices, and SortByPType. Supplying postProcess is an exact replacement. assimpCapabilities.postProcess publishes every supported named step, bit value, description, and conflict.
Production build
The artifact compiles and links with -O3 -DNDEBUG, fixed SIMD, mimalloc, Wasm exceptions, Closure-compiled glue, constructor evaluation, and standalone wasm-opt -O4 --converge --traps-never-happen --skip-pass=code-folding. The build explicitly pins WASM_LEGACY_EXCEPTIONS=1; exnref waits until every documented host floor supports it. LTO, relaxed SIMD, pthreads, Asyncify, and mode-specific JSPI artifacts remain absent.
The build manifest records exact definitions, compile/link/optimizer flags, import/export inventory, and raw/gzip/brotli size. CI ratchets those measured files rather than estimating them.