TypeScript API Reference¶
API documentation for the published TypeScript packages.
ifc-lite ships 36 public npm packages: 35 scoped @ifc-lite/* packages plus the create-ifc-lite scaffolder. This page lists all of them, with API detail for the core packages. Exact type signatures live in each package's src/index.ts and shipped .d.ts files.
Package Index¶
| Package | Description |
|---|---|
@ifc-lite/parser |
IFC/STEP parser for IFC-Lite |
@ifc-lite/geometry |
Geometry processing bridge for IFC-Lite - exact-arithmetic CSG, streamed across workers |
@ifc-lite/data |
Columnar data structures for IFC-Lite |
@ifc-lite/query |
Query system for IFC-Lite |
@ifc-lite/spatial |
Spatial indexing for IFC-Lite |
@ifc-lite/renderer |
WebGPU renderer for IFC-Lite |
@ifc-lite/export |
Export formats for IFC-Lite |
@ifc-lite/mutations |
Mutation tracking and property editing for IFC-Lite |
@ifc-lite/create |
IFC creation from scratch — walls, slabs, beams, columns, stairs, roofs with geometry, properties and quantities |
@ifc-lite/bcf |
BIM Collaboration Format (BCF) support for IFC-Lite |
@ifc-lite/ids |
IDS (Information Delivery Specification) support for IFC-Lite |
@ifc-lite/drawing-2d |
2D architectural drawing generation from IFC models - section cuts, floor plans, and elevations |
@ifc-lite/clash |
Clash detection for IFC-Lite — representation-agnostic core engine + source adapters |
@ifc-lite/diff |
Headless model-diff engine for IFC-Lite — classifies entities as added/modified/deleted/unchanged across two revisions, with separable data vs geometry scope. |
@ifc-lite/lens |
Rule-based 3D filtering and colorization for IFC models |
@ifc-lite/lists |
Configurable property tables and schedules from IFC data for IFC-Lite |
@ifc-lite/ifcx |
IFC5 (IFCX) parser for IFC-Lite |
@ifc-lite/encoding |
IFC string encoding/decoding and property value parsing for IFC-Lite |
@ifc-lite/cache |
Binary cache format for IFC-Lite - fast model loading |
@ifc-lite/pointcloud |
Point cloud decoders and types for IFC-Lite |
@ifc-lite/solar |
Solar position, sunrise/sunset and 3D sun-path geometry for IFC-Lite |
@ifc-lite/sdk |
Scripting SDK for ifc-lite — the bim.* API for BIM automation |
@ifc-lite/sandbox |
QuickJS-in-WASM sandboxed script execution for ifc-lite |
@ifc-lite/extensions |
Extension manifest, capability grammar, and slot registry for ifc-lite user customization |
@ifc-lite/mcp |
Model Context Protocol server for ifc-lite — agent-native BIM via MCP (stdio + Streamable HTTP) |
@ifc-lite/cli |
CLI toolkit for IFC files — query, validate, export, create, and script BIM data |
@ifc-lite/collab |
Real-time collaborative BIM via CRDT on IFCX |
@ifc-lite/collab-server |
Reference websocket sync server for @ifc-lite/collab |
@ifc-lite/embed-sdk |
SDK for embedding the IFC-Lite 3D viewer in any web page via iframe |
@ifc-lite/embed-protocol |
Shared postMessage protocol types for ifc-lite embed viewer and SDK |
@ifc-lite/viewer-core |
Interactive 3D viewer for IFC models — WebGL 2 browser viewer with REST API |
@ifc-lite/server-client |
TypeScript client SDK for IFC-Lite Server |
@ifc-lite/server-bin |
Pre-built IFC-Lite server binary - run without Docker or Rust |
@ifc-lite/wasm |
WebAssembly bindings for IFC-Lite |
@ifc-lite/codegen |
TypeScript code generator from IFC EXPRESS schemas |
create-ifc-lite |
Create IFC-Lite projects with one command |
@ifc-lite/merge |
Three-way merge engine for IFCX layers — MergePlan with auto-merged ops and explicit conflict records, merge-layer emission, rebase, and revert. |
@ifc-lite/oauth-pkce |
Browser OAuth 2.0 Authorization Code + PKCE flow, shared by ifc-lite's file-source providers |
@ifc-lite/plugin-api |
Dependency-free type surface for ifc-lite file-source plugins |
@ifc-lite/source-dalux |
Dalux Build (Box) file-source provider for ifc-lite |
@ifc-lite/source-dropbox |
Dropbox file-source provider for ifc-lite |
@ifc-lite/source-msgraph |
Microsoft Graph (OneDrive/SharePoint) file-source provider for ifc-lite |
@ifc-lite/parser¶
IFC/STEP parser producing a columnar IfcDataStore.
IfcParser¶
class IfcParser {
// Columnar parse (recommended). Accepts ArrayBuffer or SharedArrayBuffer.
parseColumnar(buffer: ArrayBuffer | SharedArrayBuffer, options?: ParseOptions): Promise<IfcDataStore>;
// Legacy eager parse into a ParseResult (deprecated, kept as a compatibility adapter)
parse(buffer: ArrayBuffer, options?: ParseOptions): Promise<ParseResult>;
}
ParseOptions¶
interface ParseOptions {
onProgress?: (progress: { phase: string; percent: number }) => void;
onDiagnostic?: (message: string) => void;
// Optional IfcAPI instance for WASM-accelerated entity scanning
wasmApi?: WasmScanApi;
// Yield budget for large incremental parses
yieldIntervalMs?: number;
// Defer indexing of individual property/quantity atoms
deferPropertyAtomIndex?: boolean;
// Skip worker-based entity scanning and stay in-process
disableWorkerScan?: boolean;
// Called when the spatial hierarchy is ready, before property parsing completes
onSpatialReady?: (partialStore: IfcDataStore) => void;
// Pre-built entity index from another worker (e.g. the geometry pre-pass)
preScannedEntityIndex?: PreScannedEntityIndex;
}
parseAuto¶
Auto-detects the file format (IFC/STEP vs IFCX/JSON, with transparent .ifcZIP unwrap) and parses accordingly.
import { parseAuto } from '@ifc-lite/parser';
const result = await parseAuto(buffer);
if (result.format === 'ifc') {
const store = result.data; // IfcDataStore
} else {
const ifcx = result.data; // IfcxParseResult
const meshes = result.meshes; // pre-extracted meshes
}
IfcDataStore¶
Result of parseColumnar(). Key fields (see src/columnar-parser.ts for the full interface):
interface IfcDataStore extends IfcStoreBase {
source: Uint8Array;
entityIndex: { byId: EntityByIdIndex; byType: Map<string, number[]> };
strings: StringTable;
entities: EntityTable;
properties: PropertyTable;
quantities: QuantityTable;
relationships: RelationshipGraph;
parseTime: number;
// Length unit scale to metres (e.g. 0.001 for mm files)
lengthUnitScale?: number;
// On-demand lookup maps: entityId -> related expressIds
onDemandPropertyMap?: Map<number, number[]>;
onDemandQuantityMap?: Map<number, number[]>;
onDemandClassificationMap?: Map<number, number[]>;
onDemandMaterialMap?: Map<number, number>;
onDemandDocumentMap?: Map<number, number[]>;
}
On-Demand Extraction¶
Properties, quantities, and attributes are extracted lazily for memory efficiency.
import {
extractPropertiesOnDemand,
extractQuantitiesOnDemand,
extractEntityAttributesOnDemand,
} from '@ifc-lite/parser';
// Property sets for one entity
const psets = extractPropertiesOnDemand(store, expressId);
// Quantity sets for one entity
const qsets = extractQuantitiesOnDemand(store, expressId);
// Root attributes for one entity
const attrs = extractEntityAttributesOnDemand(store, expressId);
// { globalId, name, description, objectType, tag }
Many more on-demand extractors are exported (classifications, materials, documents, relationships, group members, georeferencing, type properties, schedules); see packages/parser/src/index.ts.
secondsToIso8601Duration(seconds: number): string | undefined is a new export: it renders a signed number of seconds as an ISO 8601 duration string suitable for IfcDuration (86400 -> "P1D", -172800 -> "-P2D"), preferring the coarsest whole unit that divides cleanly and falling back to a decimal-seconds form for fractional values. It returns undefined for non-finite input (NaN, ±Infinity) rather than fabricating "PT0S". parseIso8601Duration(value: string | undefined): number | undefined is its decode counterpart — already public before this change — and the two form a round trip: parseIso8601Duration(secondsToIso8601Duration(s)) === s for every finite, representable s. Both also accept/emit the ISO 8601-2 signed extension (-P2D) to carry IFC schedule lead time; see docs/guide/schedule-import.md.
Other exports include the STEP scanning/tokenizing building blocks (StepTokenizer, EntityExtractor, scanIfcEntities, CompactEntityIndex), unit extraction (extractProjectUnits, ProjectUnits), the STEP serializer helpers (generateStepFile, toStepLine, serializeValue), the generated IFC schema registry (SCHEMA_REGISTRY, getAttributeNames), and re-exported IFCX parsing from @ifc-lite/ifcx.
@ifc-lite/geometry¶
Bridge from IFC bytes to per-element triangle meshes, running the Rust kernel via WASM (or a native backend when available).
GeometryProcessor¶
class GeometryProcessor {
constructor(options?: GeometryProcessorOptions);
// Initialize WASM (required before processing)
init(): Promise<void>;
// Process IFC buffer and extract geometry (whole-file)
process(buffer: Uint8Array, entityIndex?: Map<number, any>): Promise<GeometryResult>;
// Stream geometry for large files (async generator of streaming events)
processStreaming(/* buffer + streaming options; see the .d.ts */): AsyncGenerator<StreamingGeometryEvent>;
// Rust-side exporters surfaced on the processor
exportGlb(buffer, includeMetadata?, hidden?, isolated?, hiddenTypesCsv?, lit?): Uint8Array | null;
exportGlbFromMeshes(meshes: MeshData[], includeMetadata?, lit?): Uint8Array | null;
exportObj(/* ... */): Uint8Array | null;
exportCsv(/* buffer, mode: 'entities'|'properties'|'quantities'|'spatial', ... */): Uint8Array | null;
exportJson(/* ... */): Uint8Array | null;
exportJsonld(/* ... */): Uint8Array | null;
exportStep(/* ... */): Uint8Array | null;
exportIfcx(buffer, onlyKnownProperties?, pretty?): Uint8Array | null;
exportMerged(buffers: Uint8Array[], schema?): Uint8Array | null;
exportKmz(/* ... */): Uint8Array | null;
exportHbjson(buffer, name): Uint8Array | null;
}
GeometryResult and MeshData¶
interface GeometryResult {
meshes: MeshData[];
pointClouds?: PointCloudAsset[];
totalTriangles: number;
totalVertices: number;
coordinateInfo: CoordinateInfo;
}
interface MeshData {
expressId: number;
ifcType?: string;
modelIndex?: number;
positions: Float32Array; // [x,y,z, ...]
normals: Float32Array; // [nx,ny,nz, ...]
indices: Uint32Array; // triangle indices (winding is unreliable; meshes are double-sided)
color: [number, number, number, number];
// ... local-frame origin, geometry class, texture fields; see src/types.ts
}
CoordinateInfo carries the RTC/origin-shift information (originShift, wasmRtcOffset, hasLargeCoordinates, buildingRotation, unit scale) needed to place meshes in world space.
@ifc-lite/data¶
Columnar data structures shared by the parser and downstream packages.
Key exports:
// Deduplicated string storage
class StringTable { get(index: number): string; intern(value: string): number; /* ... */ }
// Columnar tables: built once, read everywhere
class EntityTableBuilder { /* build(): EntityTable */ }
class PropertyTableBuilder { /* build(): PropertyTable */ }
class QuantityTableBuilder { /* build(): QuantityTable */ }
// CSR-format relationship graph
class RelationshipGraphBuilder { /* build(): RelationshipGraph */ }
Each table type also has fromColumns / toColumns helpers for structured-clone transfer across workers (entityTableFromColumns, propertyTableToColumns, ...). Shared enums and types live here too: IfcTypeEnum, PropertyValueType, QuantityType, RelationshipType, SpatialHierarchy, IfcStoreBase, the generated entity-name lists (ENTITIES_IFC2X3 / IFC4 / IFC4X3), plus utilities like safeUtf8Decode and createLogger.
IFC_DATA_TYPES sits alongside those entity lists: the raw, read-only table of EXPRESS defined types (IfcLengthMeasure, IfcBoolean, IfcTextAlignment, ...) across all three schemas. The upstream data the ENTITIES_* lists come from carries defined types as entity rows, so any synchronous consumer deciding "is this name a real class?" has to subtract this table — that is what @ifc-lite/parser's isKnownType does. Prefer the async findDataType(version, name) when you only need a single lookup and are not inside a synchronous guard.
@ifc-lite/parser exports two type predicates, and they answer different questions:
| predicate | question | IfcWall |
IfcProduct |
IfcLengthMeasure |
|---|---|---|---|---|
isKnownType |
is this a real EXPRESS entity name? | true |
true |
false |
isInstantiable |
may I author an entity of this class? | true |
false |
false |
IfcProduct is the distinction: it is a real class, so isKnownType accepts it, but it is an EXPRESS ABSTRACT SUPERTYPE and cannot legally exist as an instance. Roughly 123 classes are abstract in this way. Use isInstantiable for anything that creates entities (bim.store.addEntity, the MCP entity_create tool); isKnownType is for recognising a name you have read, not for authoring. Both resolve across the union of the bundled schemas, so IFC4X3-only classes such as IfcSignal behave the same under either.
@ifc-lite/query¶
IfcQuery¶
Fluent query builder over an IfcDataStore.
class IfcQuery {
constructor(store: IfcDataStore);
// Type shortcuts -> EntityQuery
walls(): EntityQuery; // IfcWall + IfcWallStandardCase
doors(): EntityQuery;
windows(): EntityQuery;
slabs(): EntityQuery;
columns(): EntityQuery;
beams(): EntityQuery;
spaces(): EntityQuery;
// Type filter (variadic), everything, and by id
ofType(...types: string[]): EntityQuery;
all(): EntityQuery;
byId(expressId: number): EntityQuery;
// Spatial
onStorey(storeyId: number): EntityQuery;
inBounds(aabb: AABB): EntityQuery;
raycast(origin: [number, number, number], direction: [number, number, number]): number[];
// Graph navigation
entity(expressId: number): EntityNode;
get storeys(): EntityNode[];
get project(): EntityNode | null;
// SQL (DuckDB-WASM, lazily initialized on first call)
sql(query: string): Promise<SQLResult>;
}
EntityQuery¶
class EntityQuery {
whereProperty(psetName: string, propName: string, operator: ComparisonOperator, value: unknown): this;
limit(count: number): this;
offset(count: number): this;
includeGeometry(): this;
includeProperties(): this;
includeQuantities(): this;
includeAll(): this;
// Terminals
execute(): QueryResultEntity[];
ids(): Promise<number[]>;
count(): Promise<number>;
first(): Promise<QueryResultEntity | null>;
}
EntityNode¶
Single-entity graph navigation, from IfcQuery.entity(id) or IfcQuery.storeys.
class EntityNode {
// Spatial containment
contains(): EntityNode[];
containedIn(): EntityNode | null;
storey(): EntityNode | null;
building(): EntityNode | null;
// Aggregation and typing
decomposes(): EntityNode[];
decomposedBy(): EntityNode | null;
definingType(): EntityNode | null;
instances(): EntityNode[];
// Voids and fills
voids(): EntityNode[];
filledBy(): EntityNode[];
// Data
properties(): PropertySet[];
quantities(): QuantitySet[];
allAttributes(): Array<{ name: string; value: string | number | boolean }>;
// Generic traversal
traverse(relType: RelationshipType, depth: number, direction?: 'forward' | 'inverse'): EntityNode[];
}
@ifc-lite/spatial¶
Spatial indexing utilities for geometry queries and frustum culling.
buildSpatialIndex¶
import { buildSpatialIndex, buildSpatialIndexAsync } from '@ifc-lite/spatial';
import type { MeshData } from '@ifc-lite/geometry';
function buildSpatialIndex(meshes: MeshData[]): SpatialIndex;
Example:
import { GeometryProcessor } from '@ifc-lite/geometry';
import { buildSpatialIndex } from '@ifc-lite/spatial';
import { Renderer } from '@ifc-lite/renderer';
const geometry = new GeometryProcessor();
await geometry.init();
const result = await geometry.process(new Uint8Array(buffer));
// Build spatial index for frustum culling
const spatialIndex = buildSpatialIndex(result.meshes);
const renderer = new Renderer(canvas);
await renderer.init();
renderer.loadGeometry(result);
// Render with frustum culling
renderer.render({
enableFrustumCulling: true,
spatialIndex
});
SpatialIndex¶
interface SpatialIndex {
// Query AABB: expressIds of meshes intersecting bounds
queryAABB(bounds: AABB): number[];
// Raycast: expressIds of meshes hit by ray
raycast(origin: [number, number, number], direction: [number, number, number]): number[];
// Query frustum: expressIds of meshes visible in frustum
queryFrustum(frustum: Frustum): number[];
}
The underlying BVH class, AABBUtils, and FrustumUtils are also exported.
@ifc-lite/renderer¶
Renderer¶
WebGPU-based 3D renderer.
class Renderer {
constructor(canvas: HTMLCanvasElement);
// Initialize WebGPU
init(): Promise<void>;
// Load geometry (main entry point for IFC geometry)
loadGeometry(geometry: GeometryResult | MeshData[]): void;
// Add meshes incrementally (for streaming)
addMeshes(meshes: MeshData[], isStreaming?: boolean): void;
// Rendering
render(options?: RenderOptions): void;
// Camera controls
fitToView(): void;
getCamera(): Camera;
// Selection (GPU picking)
pick(x: number, y: number, options?: PickOptions): Promise<PickResult | null>;
// Scene access
getScene(): Scene;
getPipeline(): RenderPipeline | null;
getGPUDevice(): GPUDevice | null;
isReady(): boolean;
// Resize handling
resize(width: number, height: number): void;
}
Visibility is passed via render() options (hiddenIds, isolatedIds); frustum culling via enableFrustumCulling plus a spatialIndex from @ifc-lite/spatial.
Other exports: Camera, Scene, Picker, PickingManager, Raycaster, SnapDetector, BVH, SectionPlaneRenderer, Section2DOverlayRenderer, PointCloudRenderer, FederationRegistry (multi-model id ranges), and the section-cap / plane-basis helpers.
@ifc-lite/export¶
Client-side exporters that operate on a parsed IfcDataStore.
StepExporter¶
Export IFC models back to STEP, with optional visible-only filtering and mutation baking.
class StepExporter {
constructor(dataStore: IfcDataStore, mutationView?: MutablePropertyView);
export(options: StepExportOptions): StepExportResult;
}
interface StepExportOptions {
// Output schema; converts entity types when needed
schema: 'IFC2X3' | 'IFC4' | 'IFC4X3' | 'IFC5';
description?: string;
author?: string;
organization?: string;
application?: string;
filename?: string;
includeGeometry?: boolean; // default true
includeProperties?: boolean; // default true
includeQuantities?: boolean; // default true
includeRelationships?: boolean; // default true
applyMutations?: boolean; // bake MutablePropertyView edits
deltaOnly?: boolean; // only entities with mutations
visibleOnly?: boolean; // filter to viewer-visible entities
hiddenEntityIds?: Set<number>; // required when visibleOnly is true
// ... isolation, progress; see src/step-exporter.ts
}
MergedExporter¶
Merge multiple IFC models into a single STEP file with a unified ID space, spatial-hierarchy unification, and unit-aware reconciliation.
class MergedExporter {
constructor(models: MergeModelInput[]);
export(options: MergeExportOptions): MergeExportResult; // synchronous
exportAsync(options: MergeExportOptions): Promise<MergeExportResult>; // progress + mutations
}
MergeExportOptions.unitReconciliation controls mixed length units:
'auto'(default): a model with a different length unit is federated as its ownIfcProject'normalize': rescale it into the first model's unit (one single-unit project)'assume-shared': force one project without rescaling
Spatial matching is tunable per container type via mergeSites / mergeBuildings ('single' | 'by-name') and mergeStoreys ('by-name' | 'by-elevation' | 'by-name-then-elevation').
ParquetExporter¶
Creates a .bos archive (ZIP of Parquet files) from a parsed store, optionally with geometry buffers.
class ParquetExporter {
constructor(store: IfcDataStore, geometryResult?: GeometryResult);
exportBOS(options?: ParquetExportOptions): Promise<Uint8Array>;
exportTable(tableName: string): Promise<Uint8Array>;
}
Reference Collection¶
Low-level closure walking for valid STEP export:
// Forward closure walk from root entities
function collectReferencedEntityIds(
rootIds: Set<number>,
source: Uint8Array,
entityIndex: { get(id: number): { byteOffset: number; byteLength: number } | undefined; has(id: number): boolean },
excludeIds?: Set<number>,
): Set<number>;
// Resolve viewer visibility into export roots
function getVisibleEntityIds(dataStore, hiddenIds, isolatedIds): { roots: Set<number>; hiddenProductIds: Set<number> };
// Reverse pass adding IfcStyledItem entities into the closure (mutates `closure`)
function collectStyleEntities(closure: Set<number>, source: Uint8Array, entityIndex): void;
Other exports¶
Ifc5Exporter: IFC5/IFCX JSON export- Schema conversion helpers:
convertEntityType,convertStepLine,needsConversion - GLB helpers:
parseGLB,parseGLBToMeshData,extractGlbMapping,countGlbMeshes - LOD generators:
generateLod0,generateLod1
glTF / GLB and CSV export¶
The standalone GltfExporter and CsvExporter classes were removed. glTF/GLB and CSV are produced in Rust and exposed on GeometryProcessor (from @ifc-lite/geometry): exportGlb(buffer, ...), exportGlbFromMeshes(meshes, ...), and exportCsv(buffer, mode, ...) where mode is one of entities, properties, quantities, or spatial.
@ifc-lite/mutations¶
Property editing with bidirectional change tracking. Nothing mutates the parsed buffer; edits accumulate in an overlay and materialise during StepExporter.export({ applyMutations: true }).
MutablePropertyView¶
Wraps a PropertyTable with a mutation overlay for non-destructive property editing.
class MutablePropertyView {
constructor(baseTable: PropertyTable | null, modelId: string);
// Reads (with mutations applied)
getForEntity(entityId: number): PropertySet[];
getPropertyValue(entityId: number, psetName: string, propName: string): PropertyValue | null;
// Property edits (each returns/records a Mutation)
setProperty(entityId, psetName, propName, value, valueType?, unit?): Mutation;
deleteProperty(entityId, psetName, propName): Mutation | null;
createPropertySet(entityId, psetName, properties): Mutation;
deletePropertySet(entityId, psetName): Mutation;
// Positional STEP-argument overrides (profiles, points, ...)
setPositionalAttribute(entityId, index, value, skipHistory?): Mutation;
getPositionalMutationsForEntity(entityId): Map<number, IfcAttributeValue> | null;
removePositionalMutation(entityId, index): void;
// Entity churn in the overlay
createEntity(type: string, attributes: IfcAttributeValue[]): NewEntity;
deleteEntity(expressId: number): boolean;
getNewEntities(): NewEntity[];
isDeleted(expressId: number): boolean;
getTombstones(): Set<number>;
restoreFromTombstone(expressId: number): boolean;
// Bookkeeping
getMutations(): Mutation[];
hasChanges(entityId?: number): boolean;
applyMutations(mutations: Mutation[]): void;
exportMutations(): string;
importMutations(json: string): void;
clear(): void;
}
StoreEditor¶
High-level facade for editing a parsed IfcDataStore via the MutablePropertyView overlay.
import { MutablePropertyView, StoreEditor } from '@ifc-lite/mutations';
const view = new MutablePropertyView(propertyTable, modelId);
const editor = new StoreEditor(dataStore, view);
const profile = editor.addEntity('IFCRECTANGLEPROFILEDEF', [
'.AREA.', null, '#34', 0.6, 0.4,
]);
editor.setPositionalAttribute(profile.expressId, 3, 0.7);
editor.removeEntity(unwantedExpressId);
class StoreEditor {
constructor(store: IfcDataStore, view: MutablePropertyView);
// Add a new entity to the overlay (returns a synthetic EntityRef with a fresh expressId)
addEntity(type: string, attributes: IfcAttributeValue[]): EntityRef;
// Tombstone an existing entity or forget an overlay-only one
removeEntity(expressId: number): boolean;
// Override a single positional STEP arg by zero-based index
setPositionalAttribute(expressId: number, index: number, value: IfcAttributeValue): void;
// Edit a named root attribute (Name, Description, ObjectType, ...)
setAttribute(expressId: number, attrName: string, value: string): void;
getNewEntity(expressId: number): NewEntity | null;
getNewEntities(): NewEntity[];
}
Value conventions¶
addEntity and setPositionalAttribute accept the same shape that EntityExtractor.extractEntity().attributes produces:
| JS value | STEP literal |
|---|---|
null / undefined |
$ |
42 / 0.6 |
integer / REAL |
true / false |
.T. / .F. |
"#42" (string) |
entity reference |
".AREA." (string) |
enum |
"My Column" (string) |
quoted STEP string |
[1, 2, 3] |
STEP list (1,2,3), recursive |
ChangeSetManager¶
Manage named groups of mutations: createChangeSet, setActiveChangeSet, addMutation, mergeChangeSets, exportChangeSet / importChangeSet, and friends.
BulkQueryEngine¶
Query and update entities in bulk.
class BulkQueryEngine {
select(criteria: SelectionCriteria): number[];
preview(query: BulkQuery): BulkQueryPreview;
execute(query: BulkQuery): BulkQueryResult;
}
CsvConnector¶
Import property updates from CSV files: parse, match, generateMutations, import, preview, autoDetectMappings.
Mutation types cover properties (CREATE/UPDATE/DELETE_PROPERTY, CREATE/DELETE_PROPERTY_SET), quantities, named attributes (UPDATE_ATTRIBUTE), positional STEP args (UPDATE_POSITIONAL_ATTRIBUTE), and entity churn (CREATE_ENTITY, DELETE_ENTITY).
@ifc-lite/create¶
Build valid IFC4 STEP files programmatically, or add elements into an already-parsed model.
IfcCreator¶
import { IfcCreator } from '@ifc-lite/create';
const creator = new IfcCreator({ Name: 'My Project' });
const storey = creator.addIfcBuildingStorey({ Name: 'Ground Floor', Elevation: 0 });
creator.addIfcWall(storey, {
Start: [0, 0, 0], End: [5, 0, 0],
Thickness: 0.2, Height: 3,
});
const { content } = creator.toIfc();
Coordinates are storey-relative. Every addIfc*(storeyId, …) method chains the product's IfcLocalPlacement to that storey's placement, and the storey placement is where Elevation is applied — exactly once. An element standing on the floor of a storey at Elevation: 3 is created with Z = 0, not Z = 3; adding the elevation yourself puts it at twice the height. (addIfcWallDoor and addIfcWallWindow are the exception: their Position is wall-local, and they inherit the storey datum through their host wall.)
class IfcCreator {
constructor(params?: ProjectParams);
// Spatial structure
addIfcBuildingStorey(params: StoreyParams): number;
// Building elements (each returns the new expressId)
addIfcWall(storeyId, params: WallParams): number;
addIfcSlab(storeyId, params: SlabParams): number;
addIfcColumn(storeyId, params: ColumnParams): number;
addIfcBeam(storeyId, params: BeamParams): number;
addIfcStair(storeyId, params: StairParams): number;
addIfcRoof(storeyId, params: RoofParams): number;
addIfcGableRoof(storeyId, params: GableRoofParams): number;
addIfcDoor(storeyId, params: DoorParams): number;
addIfcWindow(storeyId, params: WindowParams): number;
addIfcWallDoor(wallId, params: WallDoorParams): number; // door + opening in a wall
addIfcWallWindow(wallId, params: WallWindowParams): number;
addIfcRamp(storeyId, params: RampParams): number;
addIfcRailing(storeyId, params: RailingParams): number;
addIfcPlate(storeyId, params: PlateParams): number;
addIfcMember(storeyId, params: MemberParams): number;
addIfcFooting(storeyId, params: FootingParams): number;
addIfcPile(storeyId, params: PileParams): number;
addIfcSpace(storeyId, params: SpaceParams): number;
// Properties, quantities, materials, colour
addIfcPropertySet(elementId, pset: PropertySetDef): number;
addIfcElementQuantity(elementId, qset: QuantitySetDef): number;
addIfcMaterial(elementId, material: MaterialDef): void;
setColor(elementId, name: string, rgb: [number, number, number]): void;
// Generate STEP file
toIfc(): CreateResult;
}
interface ProjectParams {
Name?: string;
Description?: string;
Schema?: 'IFC2X3' | 'IFC4' | 'IFC4X3';
LengthUnit?: string; // 'METRE' (default), 'MILLIMETRE', 'FOOT'
Author?: string;
Organization?: string;
Timestamp?: number | Date; // fixed creation instant (header + owner history); default: wall clock
GuidSource?: () => string; // deterministic GlobalId source; default: platform CSPRNG
}
For byte-reproducible output (fixtures, snapshot tests, generated corpora), pin both entropy sources — the timestamp and the GlobalId stream:
import { IfcCreator } from '@ifc-lite/create';
import { generateIfcGuid, type RandomSource } from '@ifc-lite/encoding';
// Any seeded () => number in [0, 1) works; a tiny LCG shown here.
let seed = 42;
const rng: RandomSource = () => {
seed = (seed * 1103515245 + 12345) % 2147483648;
return seed / 2147483648;
};
const creator = new IfcCreator({
Name: 'My Project',
Timestamp: Date.UTC(2024, 0, 1),
GuidSource: () => generateIfcGuid(rng),
});
// Two runs with the same seed now produce byte-identical .ifc content.
Parameter interfaces for every element type live in packages/create/src/types.ts (e.g. WallParams with Start, End, Thickness, Height, optional Openings).
In-Store Builders¶
For editing an already-parsed IfcDataStore, the package exposes anchored builders that emit a complete sub-graph (placement, profile, solid, representation, containment) into a StoreEditor overlay:
addColumnToStore, addWallToStore, addSlabToStore, addBeamToStore, addDoorToStore, addWindowToStore, addSpaceToStore, addRoofToStore, addPlateToStore, addMemberToStore.
import { StoreEditor } from '@ifc-lite/mutations';
import { addColumnToStore, resolveSpatialAnchor } from '@ifc-lite/create';
const editor = new StoreEditor(dataStore, mutationView);
const anchor = resolveSpatialAnchor(dataStore, storeyExpressId);
const result = addColumnToStore(editor, anchor, {
Position: [1, 1, 0],
Width: 0.3, Depth: 0.4, Height: 3,
Name: 'Column 1',
});
resolveSpatialAnchor¶
Walks a parsed IfcDataStore for the references every in-store builder needs. Throws if IfcOwnerHistory, the 'Body' representation context, or the storey's IfcLocalPlacement cannot be resolved.
function resolveSpatialAnchor(store: IfcDataStore, storeyExpressId: number): SpatialAnchor;
interface SpatialAnchor {
ownerHistoryId: number; // referenced by every IfcRoot
bodyContextId: number; // 'Body' subcontext (or parent context fallback)
storeyId: number;
storeyPlacementId: number; // the storey's own IfcLocalPlacement
guidRandom?: RandomSource; // optional seeded [0,1) source: pins the emitted
// GlobalIds for reproducible in-store builds
// (counterpart of ProjectParams.GuidSource)
}
duplicateInStore takes the same knob as options.guidRandom (it has no anchor), and generateSpacesFromWalls / generateSpaces forward options.guidRandom to the spaces they emit.
For byte-reproducible exported files, seed the exporter too: builders that attach property or quantity sets (e.g. addSpaceToStore) park them in the mutation overlay, and StepExporter mints the IfcPropertySet / IfcElementQuantity / IfcRelDefinesByProperties GlobalIds itself at export time. Pass the same source as StepExportOptions.guidRandom, plus timeStamp to pin the STEP header instant.
@ifc-lite/bcf¶
BCF (BIM Collaboration Format) support for issue tracking. Implements BCF 2.1 and 3.0.
readBCF / writeBCF¶
// Read a BCF/BCFzip file (accepts File, Blob, or ArrayBuffer)
function readBCF(file: File | Blob | ArrayBuffer): Promise<BCFProject>;
// Write a BCF file (returns a Blob)
function writeBCF(project: BCFProject): Promise<Blob>;
Creation and mutation helpers¶
function createBCFProject(options?: { name?: string; version?: '2.1' | '3.0' }): BCFProject;
function createBCFTopic(options: { title: string; author: string; /* ... */ }): BCFTopic;
function createBCFComment(options: { author: string; comment: string }): BCFComment;
function addTopicToProject(project: BCFProject, topic: BCFTopic): void;
function addCommentToTopic(topic: BCFTopic, comment: BCFComment): void;
function addViewpointToTopic(topic: BCFTopic, viewpoint: BCFViewpoint): void;
function updateTopicStatus(/* topic, status, ... */): void;
Viewpoints¶
// Create a viewpoint from viewer state (camera, section plane, selection, visibility, snapshot)
function createViewpoint(options): BCFViewpoint;
// Extract viewer state from a BCF viewpoint
function extractViewpointState(viewpoint: BCFViewpoint): {
camera?: ViewerCameraState;
sectionPlane?: ViewerSectionPlane;
selectedGuids: string[];
hiddenGuids: string[];
visibleGuids: string[];
coloredGuids: { color: string; guids: string[] }[];
};
Utilities¶
GUID conversion (uuidToIfcGuid, ifcGuidToUuid, generateIfcGuid, isValidIfcGuid), ARGB colour helpers (parseARGBColor, toARGBColor), 3D marker overlay (computeMarkerPositions, BCFOverlayRenderer), and createBCFFromIDSReport to turn an IDS validation report into BCF topics.
@ifc-lite/ids¶
IDS (Information Delivery Specification) validation. Implements IDS 1.0 with all facet and constraint types.
parseIDS / validateIDS¶
// Parse an IDS XML file (accepts string or ArrayBuffer)
function parseIDS(xmlContent: string | ArrayBuffer): IDSDocument;
// Run validation against IFC data
function validateIDS(
document: IDSDocument,
accessor: IFCDataAccessor,
modelInfo: IDSModelInfo,
options?: ValidatorOptions
): Promise<IDSValidationReport>;
Facet checking¶
function checkFacet(facet, entity, accessor): boolean;
function filterByFacet(facet, entities, accessor): EntityRef[];
function checkEntityFacet(facet, entity): boolean;
function checkAttributeFacet(facet, entity, accessor): boolean;
function checkPropertyFacet(facet, entity, accessor): boolean;
function checkClassificationFacet(facet, entity, accessor): boolean;
function checkMaterialFacet(facet, entity, accessor): boolean;
function checkPartOfFacet(facet, entity, accessor): boolean;
Constraints, audit, translation¶
function matchConstraint(constraint: IDSConstraint, value: unknown): boolean;
function formatConstraint(constraint: IDSConstraint): string;
function getConstraintMismatchReason(constraint: IDSConstraint, value: unknown): string;
// IDS document correctness audit
function auditIDSDocument(/* ... */): IDSAuditReport;
function auditIDSStructure(/* ... */): IDSAuditReport;
// Report localisation
function createTranslationService(locale: 'en' | 'de' | 'fr'): TranslationService;
@ifc-lite/drawing-2d¶
2D architectural drawing generation from 3D IFC models: section cuts, floor plans, and elevations.
High-level generation¶
class Drawing2DGenerator {
initialize(): Promise<void>;
generate(meshes: MeshData[], config: SectionConfig, options?: Partial<GeneratorOptions>): Promise<Drawing2D>;
dispose(): void;
}
function generateFloorPlan(meshes: MeshData[], elevation: number, options?: Partial<GeneratorOptions>): Promise<Drawing2D>;
function generateSection(meshes: MeshData[], axis: 'x' | 'z', position: number, options?: Partial<GeneratorOptions>): Promise<Drawing2D>;
function createSectionConfig(axis: 'x' | 'y' | 'z', position: number, options?: Partial<Omit<SectionConfig, 'plane'>>): SectionConfig;
Pipeline pieces¶
- Section cutting:
SectionCutter,cutMeshesStreaming, GPU-acceleratedGPUSectionCutter+isGPUComputeAvailable - Polygons:
PolygonBuilder,simplifyPolygon,polygonBounds - Edges and visibility:
EdgeExtractor,HiddenLineClassifier,projectProfiles - Hatching:
HatchGenerator,HATCH_PATTERNS,getHatchPattern - Openings and symbols:
buildOpeningRelationships,generateDoorSymbol,generateWindowSymbol,generateStairArrow - Graphic overrides:
GraphicOverrideEngine,createOverrideEngine, presetsARCHITECTURAL_PRESETandFIRE_SAFETY_PRESET - SVG output:
SVGExporter,exportToSVG - Sheets:
createFrame,createTitleBlock,renderFrame,renderTitleBlock,renderScaleBar,PAPER_SIZE_REGISTRY - Constants:
LINE_STYLES,COMMON_SCALES,PAPER_SIZES
@ifc-lite/clash¶
Clash detection with a representation-agnostic core engine plus source adapters. Key exports: createClashEngine (pluggable ClashBackend, including the WASM-native one), groupClashes, matchesSelector, exclusion helpers (makeExclusionSet, isExcluded, pairKey), and the shared clash types.
@ifc-lite/diff¶
Headless model-diff engine: classifies entities as added / modified / deleted / unchanged across two revisions, with separable data vs geometry scope. Main entry point: diffModels.
@ifc-lite/lens¶
Rule-based 3D filtering and colorization for IFC models: evaluateLens, evaluateAutoColorLens, matchesCriteria, class/data-source discovery (discoverClasses, discoverDataSources), and BUILTIN_LENSES presets.
@ifc-lite/lists¶
Configurable property tables and schedules from IFC data: executeList, listResultToCSV, summariseListRows, column discovery (discoverColumns), name patterns (compileNameMatcher), and LIST_PRESETS.
@ifc-lite/ifcx¶
IFC5 (IFCX) parser: parseIfcx, parseFederatedIfcx, composeIfcx, detectFormat, layer stacking (createLayerStack, addIfcxOverlay), entity/property/geometry extractors, and hierarchy building. Re-exported through @ifc-lite/parser for parseAuto.
@ifc-lite/encoding¶
IFC string encoding/decoding and property value parsing: decodeIfcString, encodeIfcString, parsePropertyValue.
@ifc-lite/cache¶
Binary cache format for fast model loading: BinaryCacheWriter, BinaryCacheReader, plus hashing (xxhash64) and buffer utilities. Used by the viewer to skip re-parsing unchanged files.
@ifc-lite/pointcloud¶
Point cloud decoders and types: decodePcd, LAS/LAZ support including LasStreamingSource for chunked streaming, and decompressLZF.
@ifc-lite/solar¶
Solar position, sunrise/sunset, and 3D sun-path geometry: sunPosition, sunTimes, and the sun-path dome builders (day paths, hourly analemmas). Renderer-agnostic.
@ifc-lite/sdk¶
Scripting SDK: the bim.* API for BIM automation. createBimContext builds a BimContext whose namespaces (QueryNamespace, ModelNamespace, ViewerNamespace, MutateNamespace, StoreNamespace, ...) run against either the browser viewer or a headless backend.
@ifc-lite/sandbox¶
QuickJS-in-WASM sandboxed script execution: createSandbox / Sandbox, buildBridge (marshals the bim.* API across the sandbox boundary), and transpileTypeScript.
buildBridge returns { logs, resetLogs, dispose }. resetLogs is part of the contract, not an implementation detail: the console capture budget (byte total and entry count) is scoped to one run, so a caller driving buildBridge directly must invoke resetLogs() at the start of every run. Skip it and a script that exhausts the budget silences the logs of every later run on the same bridge. Sandbox.eval already does this for you — only direct buildBridge callers carry the obligation.
@ifc-lite/extensions¶
Extension manifest, capability grammar, and slot registry for user customization: validateManifest, migrateManifest, SlotRegistry, capability and when-clause evaluation, bundle and storage helpers.
@ifc-lite/mcp¶
Model Context Protocol server for ifc-lite: agent-native BIM via MCP over stdio or Streamable HTTP. Exports MCPServer plus the model-registry and tool-context types; also ships the ifc-lite-mcp CLI entry point.
@ifc-lite/cli¶
CLI toolkit for IFC files (binary name ifc-lite): query, validate (IDS), export (CSV/JSON/IFC/glTF/Parquet), create, merge, convert, diff, clash-check, and script the SDK.
@ifc-lite/collab¶
Real-time collaborative BIM via CRDT on IFCX: document schema, entity/relationship/geometry operations, and snapshot support.
@ifc-lite/collab-server¶
Reference websocket sync server for @ifc-lite/collab.
@ifc-lite/embed-sdk¶
SDK for embedding the IFC-Lite 3D viewer in any web page via iframe. Main export: the IFCLiteEmbed class with typed commands and an EventMap for viewer events.
@ifc-lite/embed-protocol¶
Shared postMessage protocol types for the embed viewer and SDK: message envelope, inbound command and outbound event types, and PROTOCOL_VERSION.
@ifc-lite/viewer-core¶
Interactive 3D viewer for IFC models: a WebGL 2 browser viewer with a REST API. Published from packages/viewer; main export is getViewerHtml plus the server/embedding helpers.
@ifc-lite/server-client¶
TypeScript client SDK for IFC-Lite Server: typed REST client plus Parquet geometry decoding (decodeParquetGeometry, decodeOptimizedParquetGeometry).
@ifc-lite/server-bin¶
Pre-built ifc-lite-server binaries for deployment without a Rust toolchain or Docker. Installs a launcher (ifc-lite-server) that downloads and verifies the platform binary.
Supported platforms:
| Platform | Architecture |
|---|---|
linux-x64 |
x86_64 |
linux-arm64 |
aarch64 |
linux-x64-musl |
x86_64 (musl libc) |
darwin-x64 |
x86_64 (macOS) |
darwin-arm64 |
aarch64 (macOS Apple Silicon) |
win32-x64 |
x86_64 (Windows) |
@ifc-lite/wasm¶
WebAssembly bindings (the IfcAPI class and mesh/profile/clash types). See the WASM API reference.
@ifc-lite/codegen¶
TypeScript code generator from IFC EXPRESS schemas. Produces the 876-entity type definitions, CRC32 type ids, serializers, and the parser's generated Rust tables (generateTypeIds, generateSerializers, generateRust). Primarily a build-time tool, not used at runtime.
create-ifc-lite¶
Project scaffolder: npm create ifc-lite (binary create-ifc-lite) sets up a new IFC-Lite project with one command.