Skip to content

louistrue/ifc-lite

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

475 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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, 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 IFC4 / IFC4X3 (876 entities, full schema) and IFC5 (IFCX). Live demo at ifclite.com.

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

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 result = await parser.parse(buffer, {
  onProgress: ({ phase, percent }) => console.log(`${phase}: ${percent}%`),
});

console.log(`Parsed ${result.entityCount} entities in ${(performance.now() - t0).toFixed(0)}ms`);

For columnar storage (recommended for large models — TypedArray-backed, query-friendly):

const store = await parser.parseColumnar(buffer);
console.log(`${store.entityCount} entities, schema ${store.schemaVersion}`);

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 buffer = new Uint8Array(await file.arrayBuffer());
const parseResult = await parser.parse(buffer);
const meshes = await geometry.process(buffer);

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.

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

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

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, GLTFExporter, ParquetExporter, Ifc5Exporter } from '@ifc-lite/export';

// IFC STEP — applies any pending mutations
const stepText = exportToStep(store, { schema: 'IFC4', applyMutations: true });

// glTF for the web
const glb = await new GLTFExporter().export(parseResult, { format: 'glb' });

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

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
Server Teams, large files, repeat access Rust backend with caching, parallel processing, streaming
Desktop (Tauri) Offline use, very large files (500 MB+) Native app with multi-threading and direct filesystem access

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

Performance

  • First triangles: 200–500ms for a typical 50 MB model in the browser.
  • Geometry processing: up to 5× faster than web-ifc on the same hardware.
  • Bundle size: ~260 KB gzipped (parser + geometry + renderer).
  • Schema coverage: 100% of IFC4 (776 entities) and IFC4X3 (876 entities).
  • Parse throughput: ~1,259 MB/s tokenization on a typical M1 / M2 laptop.

See benchmarks for full numbers across model sizes and hardware.

Examples

Ready-to-run projects in examples/:

Documentation

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

Contributing

No Rust toolchain needed — WASM comes pre-built.

GIT_LFS_SKIP_SMUDGE=1 git clone https://github.com/louistrue/ifc-lite.git
cd ifc-lite
pnpm install && pnpm build && pnpm dev   # opens viewer at localhost:5173

For benchmark fixtures, fetch only what you need:

git lfs pull --include="tests/models/ara3d/AC20-FZK-Haus.ifc"

See the Contributing Guide and Release Process.

Community

License

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