Skip to content

LTplus-AG/ifc-lite

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,296 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

IFClite

Open, view, and work with IFC files. Right in the browser.

Try it Live

Build Status License npm parser crates.io


IFClite

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.

Get Started

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

Prefer the terminal? The whole toolkit is also a CLI:

npm install -g @ifc-lite/cli
ifc-lite info model.ifc

Parse an IFC file

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`);

View in 3D

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.

Query entities

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);

Validate against IDS

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`);
}

Edit properties (with undo)

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

Export

import { 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 });

Work from the terminal

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.

Choose your setup

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.

Pick your packages

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).

Performance

  • 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.

Examples

Ready-to-run projects in examples/:

Documentation

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

Contributing

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.

Community

License

MPL-2.0 - use, modify, redistribute. Source files modified under MPL must remain MPL.

About

Parse, view, query, edit, and export IFC, IDS, BCF, pointclouds and more AEC stuff. In the browser, server or desktop.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

268 stars

Watchers

4 watching

Forks

Sponsor this project

Contributors