by LTplus-AG
Parse, view, query, edit, and export IFC, IDS, BCF, pointclouds and other AEC data directly in the browser, on a server, or in a desktop app, using a Rust‑based WASM core and WebGPU rendering.
Ifc Lite provides a full‑stack solution for handling IFC and related BIM data. It exposes a Rust/WASM core for fast parsing, columnar storage, and geometry processing, and a set of TypeScript packages for rendering (WebGPU), querying, editing, validation, and exporting.
npx create-ifc-lite my-viewer --template react
cd my-viewer && npm install && npm run dev
npm install @ifc-lite/parser @ifc-lite/geometry @ifc-lite/renderer
import { IfcParser } from '@ifc-lite/parser';
const parser = new IfcParser();
const buffer = await fetch('model.ifc').then(r => r.arrayBuffer());
const store = await parser.parseColumnar(buffer);
import { GeometryProcessor } from '@ifc-lite/geometry';
import { Renderer } from '@ifc-lite/renderer';
const geometry = new GeometryProcessor();
const renderer = new Renderer(canvas);
await Promise.all([geometry.init(), renderer.init()]);
// feed meshes produced by geometry to renderer
@ifc-lite/query, @ifc-lite/mutations, @ifc-lite/ids, and @ifc-lite/export packages as demonstrated in the README.@ifc-lite/bcf and use the provided client APIs to create, read, and sync BCF topics.Parse, view, query, edit, and export IFC files in the browser. Rust + WASM core, WebGPU rendering, ~260 KB gzipped, 5× faster geometry than the next best option.
Works with IFC2X3, IFC4 / IFC4X3 and IFC5 (IFCX). Live demo at ifclite.com and more info here: ifclite.dev.
npx create-ifc-lite my-viewer --template react
cd my-viewer && npm install && npm run dev
That 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/renderer
import { 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 + 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';
const idsSpec = parseIDS(idsXmlContent);
const translator = createTranslationService('en');
const report = await validateIDS(idsSpec, store, { translator });
for (const spec of report.specificationResults) {
console.log(`${spec.specificationName}: ${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 / export
import { exportToStep, ParquetExporter, Ifc5Exporter } from '@ifc-lite/export';
import { GeometryProcessor } from '@ifc-lite/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 — the standalone GLTFExporter/CSVExporter/JSONLDExporter
// classes were retired.
const gp = new GeometryProcessor();
await gp.init();
const glb = gp.exportGlbFromMeshes(result.meshes); // Uint8Array (no re-mesh)
const csv = gp.exportCsv(buffer, 'entities', ',', /* includeProperties */ true);
const jsonld = gp.exportJsonld(buffer);
// Parquet — columnar, ~20× smaller than JSON, queryable from DuckDB / Polars
const parquet = await new ParquetExporter().exportEntities(parseResult);
// IFC5 / IFCX — JSON + USD geometry
const ifcx = new Ifc5Exporter(store, meshes).export({ includeGeometry: true });
| 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 |
| 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 |
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 |
| Connect to a server backend | + @ifc-lite/server-client |
| BCF issue tracking | + @ifc-lite/bcf |
Full list: API Reference (25 TypeScript packages, 4 Rust crates).
web-ifc on the same hardware.See benchmarks for full numbers across model sizes and hardware.
Ready-to-run projects in examples/:
| Start here | Quick Start · Installation · Browser Requirements |
| Guides | Parsing · Geometry · Rendering · Querying · Exporting |
| BIM features | Federation · BCF · IDS Validation · 2D Drawings · Property Editing |
| Tutorials | Build a Viewer · Three.js · Babylon.js · Custom Queries |
| Deep dives | Architecture · Data Flow · Performance |
| API | TypeScript · Rust · WASM |
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:3000
If 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 stale
The 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.
MPL-2.0 — use, modify, redistribute. Source files modified under MPL must remain MPL.
Please log in to share your review and rating for this MCP.
Explore related MCPs that share similar capabilities and solve comparable challenges
by modelcontextprotocol
A Model Context Protocol server for Git repository interaction and automation.
by zed-industries
A high‑performance, multiplayer code editor designed for speed and collaboration.
by modelcontextprotocol
Model Context Protocol Servers
by modelcontextprotocol
A Model Context Protocol server that provides time and timezone conversion capabilities.
by cline
An autonomous coding assistant that can create and edit files, execute terminal commands, and interact with a browser directly from your IDE, operating step‑by‑step with explicit user permission.
by upstash
Provides up-to-date, version‑specific library documentation and code examples directly inside LLM prompts, eliminating outdated information and hallucinated APIs.
by daytonaio
Provides a secure, elastic infrastructure that creates isolated sandboxes for running AI‑generated code with sub‑90 ms startup, unlimited persistence, and OCI/Docker compatibility.
by continuedev
Enables faster shipping of code by integrating continuous AI agents across IDEs, terminals, and CI pipelines, offering chat, edit, autocomplete, and customizable agent workflows.
by github
Connects AI tools directly to GitHub, enabling natural‑language interactions for repository browsing, issue and pull‑request management, CI/CD monitoring, code‑security analysis, and team collaboration.