
IFClite CLI
CLICLI for the open-source IFClite BIM toolkit: inspect models, query element properties, build door and window schedules, validate against IDS, run clash detection, diff versions, merge and convert, with JSON output; ifc-lite mcp lets agents query and edit BIM data directly. Needs Node.js.
|
|
|
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 modular npm packages let you pick the pieces you need. Geometry runs on an exact-arithmetic CSG kernel, verified element-by-element against IfcOpenShell across the public benchmark corpus.
Works with IFC2X3, IFC4 / IFC4X3 and IFC5 (IFCX). Live demo at ifclite.com and more info at ifclite.dev.
Get Started
For data automation, start with the headless SDK or CLI:
npm install @ifc-lite/sdk
import { readFile } from 'node:fs/promises';
import { openModel } from '@ifc-lite/sdk/headless';
const model = await openModel(await readFile('model.ifc'));
try {
if (model.report.completeness !== 'complete') throw new Error('Incomplete or unknown record coverage');
console.log(model.bim.query().byType('IfcDoor').count());
} finally {
model.close();
}
Developer workflows provides a reference model, runnable data/IDS/edit/export/geometry/service recipes, and expected results. For the terminal, run npx @ifc-lite/cli info model.ifc --json.
To scaffold a rendering integration:
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 loading and orbit/pan/zoom. 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, schedule, 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 schedule model.ifc --preset door # door schedule, csv/json/md/html
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 topic 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 (npm packages, Rust crates, and the ifclite-geom Python wheel).
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 correctness: exact-arithmetic boolean kernel — every opening is cut exactly, and the output is verified element-by-element against IfcOpenShell (99.9%+ agreement on the public benchmark corpus). Engines with approximate booleans are faster on boolean-heavy models; that trade is deliberate.
- Geometry speed: native (server/CLI, multi-threaded) beats
web-ifcon most of the benchmark corpus; in the browser the viewer streams geometry across workers so the first triangles render long before the file finishes processing. - 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 (~2.6 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/:
- 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
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 · Extending the Parser |
| 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
- GitHub Discussions - questions, ideas, show-and-tell
- Issues - bug reports and feature requests
- Releases - changelog and version notes
License
MPL-2.0 - use, modify, redistribute. Source files modified under MPL must remain MPL.
関連リソース

IFClite MCP
MCPIFClite's built-in MCP server: lets agents query and modify IFC models, run clash detection, IDS validation, version and quantity diffs, export CSV, GLB and more, and color or isolate elements in a browser 3D view. Just Node.js and an IFC file; read-only mode available.
LTplus-AG/ifc-lite426
VTracer
CLIConverts raster images like JPG and PNG to SVG, handling color tracing, black-and-white line art and unevenly lit scans, for vectorizing logos, illustrations and old drawings. The CLI is a 1.0 preview installed with cargo (needs Rust); a desktop app is also available.
visioncortex/vtracer7.3k
Pascal Agent Skills
PluginOfficial plugin for Pascal, an open-source 3D architecture editor: lets agents create, edit and validate 3D models of rooms and floors over MCP and check furniture placement for collisions or blocked doors. Local use needs the Pascal CLI (Node.js 22.13+); hosted projects need an API key.
pascalorg/editor24.9k
mcp-servers-for-revit
MCPDrive Autodesk Revit with AI: query elements, create walls, doors, windows, floors, grids, levels and rooms, tag in bulk and take material quantities. Needs Revit 2020-2026 on Windows and Node.js, with the plugin from Releases placed in the Revit add-ins folder.
mcp-servers-for-revit/mcp-servers-for-revit380
DDC Skills for AI Agents in Construction
Skill200+ skills for construction firms: export Revit, IFC and DWG quantities to Excel, estimate with international unit rates, produce daily and photo site reports, and track budget and schedule variance. Needs Python 3.9+; Revit/DWG conversion is Windows-only; some need Docker or an OpenAI key.
datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction351
Archicad Tapir MCP Server
MCPConnects to a running Archicad and exposes 190+ commands from the Tapir add-on and the official JSON API, for querying walls and other elements, batch-editing models and exporting files. Needs Archicad (Windows or macOS), Tapir and uv. Alpha: it edits the open project directly, so back up first.
SzamosiMate/tapir-archicad-MCP123