Use when loading and viewing IFC/BIM models in a Three.js scene. Prevents the common mistake of using deprecated web-ifc-three, ignoring AGPL-3.0 license implications, or loading large IFC files without streaming. Covers web-ifc (MIT), @thatopen/components (AGPL-3.0), IFC loading, spatial tree, property extraction. Keywords: IFC, BIM, web-ifc, IFC viewer, @thatopen/components, building model, architecture, IFC loading, spatial tree, BIM viewer, show IFC in browser, load building, web BIM viewer.
Use when loading and viewing IFC/BIM models in a Three.js scene. Prevents the common mistake of using deprecated web-ifc-three, ignoring AGPL-3.0 license implications, or loading large IFC files without streaming. Covers web-ifc (MIT), @thatopen/components (AGPL-3.0), IFC loading, spatial tree, property extraction. Keywords: IFC, BIM, web-ifc, IFC viewer, @thatopen/components, building model, architecture, IFC loading, spatial tree, BIM viewer, show IFC in browser, load building, web BIM viewer.
license
MIT
compatibility
Designed for Claude Code. Requires Three.js r160+.
metadata
{"author":"OpenAEC-Foundation","version":"1.0"}
threejs-impl-ifc-viewer
Quick Reference
Library Comparison
Library
License
Level
Status
Use Case
web-ifc
MIT
Low-level WASM parser
Active (v0.77+)
Custom pipelines, full control
@thatopen/components
MIT (v3.x)
High-level BIM toolkit
Active (v3.3.2+)
Full BIM viewers, rapid prototyping
@thatopen/components-front
MIT
Browser-specific extensions
Active
UI, advanced visualization
web-ifc-three
—
Deprecated bridge
DEAD
NEVER use
openbim-components (v1)
—
Deprecated toolkit
DEAD
NEVER use
Package Installation
# Low-level approach (MIT, full control)
npm install web-ifc three
# High-level approach (MIT, batteries-included)
npm install @thatopen/components @thatopen/components-front web-ifc three
Critical Warnings
LICENSE HISTORY WARNING: The @thatopen packages (v3.x) are licensed under MIT. However, older IFC.js ecosystem packages (openbim-components v1, IFC.js v0.x) used AGPL-3.0. ALWAYS verify the license of the exact package version you install. If using any package with AGPL-3.0, your entire application MUST be open-sourced under AGPL-3.0 or a compatible license.
NEVER use web-ifc-three -- it is deprecated and unmaintained. Use web-ifc directly or @thatopen/components instead.
NEVER use openbim-components (v1) -- it is deprecated. Use @thatopen/components (v3.x) instead.
NEVER load entire IFC geometry at once for files >50MB -- ALWAYS stream or load geometry on demand. WASM memory is limited and cannot be reclaimed without page reload.
NEVER forget to call ifcApi.CloseModel(modelID) after processing -- WASM memory leaks are permanent until page reload.
ALWAYS call components.dispose() when unmounting a @thatopen viewer -- failure to do so leaks GPU memory, Three.js objects, and event listeners.
ALWAYS initialize IfcAPI asynchronously -- await ifcApi.Init() MUST complete before any model operations.
Approach 1: web-ifc (Low-Level WASM Parser)
When to Use
You need full control over geometry extraction and rendering
You are building a custom rendering pipeline
You want MIT-licensed code only
You need to extract IFC properties without rendering geometry
WASM Setup
import * asWebIFCfrom'web-ifc';
const ifcApi = newWebIFC.IfcAPI();
ifcApi.SetWasmPath('./'); // MUST point to directory containing web-ifc.wasmawait ifcApi.Init(); // ALWAYS await before any operations
WASM file requirement: The web-ifc.wasm file MUST be served from a location accessible by the browser. Copy it from node_modules/web-ifc/ to your public/static directory. Bundlers like Vite require explicit configuration to serve WASM files.
// Read a specific entityconst wall = ifcApi.GetLine(modelID, wallExpressID, true); // flatten=true resolves referencesconsole.log(wall.Name?.value); // "Basic Wall:Generic - 200mm"console.log(wall.GlobalId?.value); // IFC GUID// Get all property sets for an elementconst relDefines = ifcApi.GetLineIDsWithType(modelID, WebIFC.IFCRELDEFINESBYPROPERTIES);
for (const relID of relDefines) {
const rel = ifcApi.GetLine(modelID, relID, false);
// Check if this relation references our element// rel.RelatedObjects contains expressIDs of related elements// rel.RelatingPropertyDefinition points to the property set
}
You want built-in fragment optimization for large models
You need element highlighting, section planes, or floor plans
MIT license (v3.x) is acceptable for your project
Architecture Setup
import * asOBCfrom'@thatopen/components';
const components = newOBC.Components();
const worlds = components.get(OBC.Worlds);
const world = worlds.create();
// Scene
world.scene = newOBC.SimpleScene(components);
world.scene.setup(); // Adds default lights and grid// Camera
world.camera = newOBC.SimpleCamera(components);
world.camera.controls.setLookAt(10, 10, 10, 0, 0, 0);
// Renderer (container is an HTMLDivElement)
world.renderer = newOBC.SimpleRenderer(components, container);
// ALWAYS call init after setup
components.init();
Loading IFC Files
const ifcLoader = components.get(OBC.IfcLoader);
await ifcLoader.setup(); // Downloads and initializes WASM// Load from file inputconst file = event.target.files[0];
const data = newUint8Array(await file.arrayBuffer());
const model = await ifcLoader.load(data);
// model is added to the active world automatically// model contains Three.js Group with fragment meshes
Key Components
Component
Access Pattern
Purpose
OBC.Components
new OBC.Components()
Central manager for all subsystems
OBC.Worlds
components.get(OBC.Worlds)
Multi-world environment management
OBC.SimpleScene
Constructor
Three.js scene wrapper with defaults
OBC.SimpleCamera
Constructor
Camera with built-in orbit controls
OBC.SimpleRenderer
Constructor
WebGL renderer bound to DOM element
OBC.IfcLoader
components.get(OBC.IfcLoader)
IFC file loading and fragment conversion
OBC.FragmentsManager
components.get(OBC.FragmentsManager)
Efficient batched geometry management
OBC.Highlighter
components.get(OBC.Highlighter)
Element selection and highlighting
OBC.Clipper
components.get(OBC.Clipper)
Section plane tools
OBC.Plans
components.get(OBC.Plans)
Floor plan generation
Fragment System
The fragment system converts IFC geometry into batched draw calls. This is critical for performance with large BIM models (10,000+ elements).
Each IFC type gets batched into a single fragment mesh
Fragments share materials where possible, minimizing state changes
Individual elements can still be picked, highlighted, and hidden by expressID
ALWAYS use fragments for models with >1,000 elements
Cleanup
// ALWAYS dispose when unmounting the viewer
components.dispose();
// This releases: Three.js scene, renderer, geometries, materials, textures,// WASM memory, event listeners, and all component state
IFC Spatial Tree
IFC files follow a hierarchical spatial structure:
Spatial containment is defined by IFCRELCONTAINEDINSPATIALSTRUCTURE and IFCRELAGGREGATES relationships. ALWAYS traverse these relationships to build a navigable tree -- do NOT assume flat element lists represent the building structure.
Memory Management for Large IFC Files
File Size
Strategy
<10MB
Load entirely, render all geometry at once
10-50MB
Load entirely, use fragment batching
50-200MB
Stream geometry by storey or type, dispose unused
>200MB
Server-side preprocessing into fragments, load on demand
Rules
ALWAYS monitor WASM heap usage -- web-ifc allocates in WASM linear memory which has a hard cap
ALWAYS dispose geometry that is not currently visible (off-screen storeys, hidden types)
NEVER keep duplicate geometry in both WASM and JavaScript heap
ALWAYS use BufferGeometry (never legacy Geometry)
ALWAYS call geometry.dispose() and material.dispose() when removing meshes from scene
Reference Links
references/methods.md -- Complete API signatures for web-ifc and @thatopen/components