| Open, view, and work with IFC files. Right in the browser. |
|
Parse, view, query, edit, validate, and export IFC files, entirely client-side. A Rust core compiled to WASM does the parsing and geometry, a WebGPU renderer puts it on screen, and 36 npm packages let you pick exactly the pieces you need. Geometry processing is up to 5x faster than web-ifc (median ~2.2x across the benchmark corpus).
Works with IFC2X3, IFC4 / IFC4X3 and IFC5 (IFCX). Live demo at ifclite.com and more info at ifclite.dev.
npx create-ifc-lite my-viewer --template react
cd my-viewer && npm install && npm run devThat gets you a working WebGPU IFC viewer with drag-and-drop, hierarchy, properties, and 2D drawings. Other templates: basic, threejs, babylonjs, server, server-native.
To add IFClite to an existing project:
npm install @ifc-lite/parser @ifc-lite/geometry @ifc-lite/rendererPrefer the terminal? The whole toolkit is also a CLI:
npm install -g @ifc-lite/cli
ifc-lite info model.ifcimport { IfcParser } from '@ifc-lite/parser';
const parser = new IfcParser();
const buffer = await fetch('model.ifc').then(r => r.arrayBuffer());
const t0 = performance.now();
const store = await parser.parseColumnar(buffer, {
onProgress: ({ phase, percent }) => console.log(`${phase}: ${percent}%`),
});
console.log(`${store.entityCount} entities, schema ${store.schemaVersion}`);
console.log(`Parsed in ${(performance.now() - t0).toFixed(0)}ms`);import { IfcParser } from '@ifc-lite/parser';
import { GeometryProcessor } from '@ifc-lite/geometry';
import { Renderer } from '@ifc-lite/renderer';
const parser = new IfcParser();
const geometry = new GeometryProcessor();
const renderer = new Renderer(canvas);
await Promise.all([geometry.init(), renderer.init()]);
const arrayBuffer = await file.arrayBuffer();
const store = await parser.parseColumnar(arrayBuffer);
const meshes = [];
for await (const event of geometry.processAdaptive(new Uint8Array(arrayBuffer))) {
if (event.type === 'batch') meshes.push(...event.meshes);
}
renderer.loadGeometry(meshes);
renderer.requestRender();
// Pick an entity at (x, y) in canvas pixels
const hit = await renderer.pick(120, 240);
if (hit) console.log(`Picked expressId ${hit.expressId}`);For Three.js or Babylon.js, parse and extract geometry the same way and feed meshes to your engine. See Three.js integration and Babylon.js integration.
import { IfcQuery } from '@ifc-lite/query';
const query = new IfcQuery(store);
// All external load-bearing walls
const walls = query
.ofType('IfcWall', 'IfcWallStandardCase')
.whereProperty('Pset_WallCommon', 'IsExternal', '=', true)
.whereProperty('Pset_WallCommon', 'LoadBearing', '=', true)
.execute();
console.log(`${walls.length} external load-bearing walls`);
for (const wall of walls) {
console.log(wall.name, wall.globalId);
}For more complex queries, use SQL via DuckDB-WASM:
const result = await query.sql(`
SELECT type, COUNT(*) AS n FROM entities GROUP BY type ORDER BY n DESC LIMIT 10
`);
console.table(result.rows);import { parseIDS, validateIDS, createTranslationService } from '@ifc-lite/ids';
import { createDataAccessor } from '@ifc-lite/ids/bridge';
const idsSpec = parseIDS(idsXmlContent);
const accessor = createDataAccessor(store);
const modelInfo = {
modelId: 'my-model',
schemaVersion: store.schemaVersion,
entityCount: store.entityCount,
};
const translator = createTranslationService('en');
const report = await validateIDS(idsSpec, accessor, modelInfo, { translator });
for (const spec of report.specificationResults) {
console.log(`${spec.specification.name}: ${spec.passRate}% passed`);
}import { MutablePropertyView } from '@ifc-lite/mutations';
import { PropertyValueType } from '@ifc-lite/data';
const view = new MutablePropertyView(store.properties, 'my-model');
view.setProperty(
wallExpressId,
'Pset_WallCommon',
'FireRating',
'REI 120',
PropertyValueType.Label,
);
console.log(view.getMutations()); // change history for undo / exportimport { exportToStep, ParquetExporter, Ifc5Exporter } from '@ifc-lite/export';
import { GeometryProcessor } from '@ifc-lite/geometry';
// Assumes the earlier parse/geometry steps: `store` (parsed IfcDataStore),
// `bytes` (raw IFC Uint8Array), `meshes` + `geometryResult` (from geometry).
// IFC STEP, applies any pending mutations
const stepText = exportToStep(store, { schema: 'IFC4', applyMutations: true });
// glTF / GLB, CSV and JSON-LD are assembled in Rust (ifc-lite-export)
// via the GeometryProcessor
const gp = new GeometryProcessor();
await gp.init();
const glb = gp.exportGlbFromMeshes(meshes); // Uint8Array (no re-mesh)
const csv = gp.exportCsv(bytes, 'entities', ',', /* includeProperties */ true);
const jsonld = gp.exportJsonld(bytes);
// Parquet: columnar, queryable from DuckDB / Polars
const parquet = await new ParquetExporter(store).exportTable('entities');
// IFC5 / IFCX: JSON + USD geometry
const ifcx = new Ifc5Exporter(store, geometryResult).export({ includeGeometry: true });The ifc-lite CLI covers the full toolkit: inspect, query, validate, export, create, diff, clash-check, merge, convert, and script IFC models without writing a line of app code.
ifc-lite info model.ifc # schema, entities, storeys
ifc-lite query model.ifc --type IfcWall --json # entities with properties
ifc-lite ids model.ifc requirements.ids # IDS validation
ifc-lite clash model.ifc --matrix --bcf clashes.bcfzip # clash detection to BCF
ifc-lite diff model-v1.ifc model-v2.ifc # model comparison
ifc-lite merge arch.ifc struct.ifc mep.ifc --out fed.ifc # federation
ifc-lite convert model.ifc --schema IFC4 --out out.ifc # schema conversion
ifc-lite view model.ifc # 3D viewer + REST API
ifc-lite eval model.ifc "bim.query().byType('IfcWall').count()"Building AI tooling? ifc-lite mcp model.ifc starts a Model Context Protocol server (stdio or HTTP) so agents can query and edit BIM data directly, and ifc-lite ask model.ifc "how many walls?" answers natural-language questions.
| Setup | Best for | You get |
|---|---|---|
| Browser (WebGPU) | Viewing and inspecting models | Full-featured 3D viewer, runs entirely client-side |
| Three.js / Babylon.js | Adding IFC support to an existing 3D app | IFC parsing + geometry, rendered by your engine |
| CLI | Scripting, CI pipelines, AI agents | The whole toolkit from the terminal, JSON output everywhere |
| Server | Teams, large files, repeat access | Rust backend with caching, parallel processing, streaming |
| Build for Desktop | Your own offline native app, very large files (500 MB+) | Extension points to wrap the packages in Tauri, with an optional native-Rust geometry fast path |
| Python (native wheel) | Analysis, scripting, scientific Python | pip install ifclite-geom runs the geometry kernel in-process, meshes straight to numpy |
Not sure? Start with the browser setup. You can add a server or switch engines later.
| I want to... | Packages |
|---|---|
| Parse an IFC file | @ifc-lite/parser |
| View a 3D model (WebGPU) | + @ifc-lite/geometry + @ifc-lite/renderer |
| Use Three.js or Babylon.js | + @ifc-lite/geometry (you handle the rendering) |
| Query properties and types | + @ifc-lite/query |
| Edit properties (with undo) | + @ifc-lite/mutations |
| Validate against IDS rules | + @ifc-lite/ids |
| Generate 2D drawings | + @ifc-lite/drawing-2d |
| Create IFC files from scratch | @ifc-lite/create |
| Export to glTF / IFC / Parquet | + @ifc-lite/export |
| Detect clashes | + @ifc-lite/clash |
| Diff two model versions | + @ifc-lite/diff |
| BCF issue tracking | + @ifc-lite/bcf |
| Filter and colorize in 3D by rules | + @ifc-lite/lens |
| Build schedules and property tables | + @ifc-lite/lists |
Script models with the bim.* API |
+ @ifc-lite/sdk |
| Real-time collaboration (CRDT on IFCX) | + @ifc-lite/collab + @ifc-lite/collab-server |
| Embed the viewer in any page (iframe) | + @ifc-lite/embed-sdk |
| Connect to a server backend | + @ifc-lite/server-client |
| Give AI agents BIM access (MCP) | + @ifc-lite/mcp |
Full list: API Reference (36 npm packages, 6 Rust crates on crates.io, and the ifclite-geom Python wheel on PyPI).
- Streaming first render: geometry is processed in batches, so the first triangles are on screen while the rest of the file is still parsing.
- Geometry processing: up to 5x faster than
web-ifc(median ~2.2x across the benchmark corpus). - Parse speed: STEP tokenization runs at roughly 1.2 GB/s; a full parse lands around 50 MB/s.
- Schema coverage: 100% of IFC4 (776 entities) and IFC4X3 (876 entities).
- Footprint: one lazily fetched WASM module (~1.2 MB gzipped) plus small per-package JS wrappers.
See benchmarks for full numbers across model sizes and hardware.
Ready-to-run projects in examples/:
- Three.js Viewer - IFC viewer using Three.js (WebGL)
- Babylon.js Viewer - IFC viewer using Babylon.js (WebGL)
- Collab Demo - real-time collaborative editing over websockets
- Three.js Collab - collaborative 3D viewing in Three.js
| Start here | Quick Start · Installation · CLI Toolkit · Browser Requirements |
| Guides | Parsing · Geometry · Rendering · Querying · Exporting |
| BIM features | Federation · BCF · IDS Validation · 2D Drawings · Property Editing |
| Customization | Extensions · Authoring Extensions · Flavors |
| Tutorials | Build a Viewer · Three.js · Babylon.js · Custom Queries |
| Deep dives | Architecture · Data Flow · Performance |
| API | TypeScript · Rust · WASM · Python |
The WASM bundle is built from rust/ on every fresh build, so a Rust
toolchain is required. rust-toolchain.toml pins the nightly channel
and the wasm32-unknown-unknown target. rustup show (or the
contributing setup guide) installs everything needed.
# 1. Rust toolchain (one-time)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo install wasm-pack # or: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
# 2. Clone and build
git clone https://github.com/LTplus-AG/ifc-lite.git
cd ifc-lite
pnpm install && pnpm build && pnpm dev # opens viewer at localhost:3000If you need IFC fixtures for tests, benchmarks, or stress tests, fetch them with:
pnpm fixtures # download every fixture (idempotent, hash-verified)
pnpm fixtures:check # CI-friendly: exit 1 if anything is missing or staleThe fixtures are stored on a GitHub Release and catalogued in
tests/models/manifest.json. See
tests/models/README.md for the full design and
maintainer workflow.
See the Contributing Guide and Release Process.
- GitHub Discussions - questions, ideas, show-and-tell
- Issues - bug reports and feature requests
- Releases - changelog and version notes
MPL-2.0 - use, modify, redistribute. Source files modified under MPL must remain MPL.
