-
Notifications
You must be signed in to change notification settings - Fork 1
Getting Started
Maarten Vroegindeweij edited this page Feb 18, 2026
·
1 revision
pnpm add @ifc-factory/core @ifc-factory/schemanpm install @ifc-factory/core @ifc-factory/schemayarn add @ifc-factory/core @ifc-factory/schema# Model validation, diffing, and batch operations
pnpm add @ifc-factory/ifc-utils
# Low-level STEP file I/O (for custom parsers)
pnpm add @ifc-factory/step-serializer
# EXPRESS schema parser (for custom code generation)
pnpm add @ifc-factory/express-parser-
Node.js >= 20 (uses
crypto.randomUUID()) - Module system: ESM or CJS (dual-format builds provided)
- TypeScript >= 5.0 (for full type support)
- No native dependencies — pure TypeScript, no WASM, no C++ bindings
The most common starting point: read an existing .ifc file and inspect its contents.
import { IfcModel } from '@ifc-factory/core';
import { readFileSync } from 'node:fs';
// Read the raw STEP file
const source = readFileSync('model.ifc', 'utf-8');
// Parse into an IfcModel
const model = IfcModel.fromStep(source);
// Basic model information
console.log(`Schema version: ${model.schema}`); // e.g. 'IFC4X3'
console.log(`Total entities: ${model.size}`); // e.g. 4523
console.log(`Project name: ${model.project?.Name}`); // e.g. 'My Building'
// Access a specific entity by its express ID (#123 in the STEP file)
const entity = model.get(123);
if (entity) {
console.log(`Entity type: ${entity.type}`); // e.g. 'IfcWall'
console.log(`Entity name: ${entity.Name}`); // e.g. 'Wall-001'
console.log(`Global ID: ${entity.GlobalId}`); // e.g. '2TGt$H0E5Cexq0Fmv1x7tP'
}Find entities by type, name, or custom predicates.
// Get all walls
const walls = model.getAllOfType('IfcWall');
console.log(`Found ${walls.length} walls`);
// Get all doors
const doors = model.getAllOfType('IfcDoor');
console.log(`Found ${doors.length} doors`);
// List all entity types in the model
const types = new Set<string>();
for (let id = 1; id <= model.size * 2; id++) {
const e = model.get(id);
if (e) types.add(e.type);
}
console.log('Entity types:', [...types].sort().join(', '));import { QueryBuilder } from '@ifc-factory/core';
// Find walls named "Exterior Wall"
const exteriorWalls = new QueryBuilder(model)
.ofType('IfcWall')
.whereProperty('Name', 'Exterior Wall')
.execute();
// Find the first IfcProject
const project = new QueryBuilder(model)
.ofType('IfcProject')
.first();
// Count windows
const windowCount = new QueryBuilder(model)
.ofType('IfcWindow')
.count();
// Custom predicate: walls with GlobalId starting with '2T'
const filtered = new QueryBuilder(model)
.ofType('IfcWall')
.where(entity => typeof entity.GlobalId === 'string' && entity.GlobalId.startsWith('2T'))
.execute();import { QueryBuilder, byType, byProperty, and, or, not } from '@ifc-factory/core';
// Combine filters with boolean logic
const filter = and(
byType('IfcWall'),
or(
byProperty('Name', 'Exterior Wall'),
byProperty('Name', 'Interior Wall')
)
);
const results = new QueryBuilder(model)
.where(filter)
.execute();Build a complete IFC model programmatically.
import {
IfcModel,
createSpatialStructure,
createPropertySet,
assignPropertySet,
generateIfcGuid,
} from '@ifc-factory/core';
// Create empty model
const model = new IfcModel();
// Build the spatial hierarchy: Project → Site → Building → Storeys
const { project, site, building, storeys } = createSpatialStructure(model, {
projectName: 'Residential Tower',
siteName: 'Amsterdam Noord',
buildingName: 'Tower A',
storeyNames: ['Basement', 'Ground Floor', 'Floor 1', 'Floor 2', 'Floor 3'],
});
console.log(`Project ID: #${project.expressID}`);
console.log(`Building ID: #${building.expressID}`);
console.log(`Storeys: ${storeys.map(s => s.Name).join(', ')}`);
// Create a wall entity
const wall = model.create('IfcWall', {
GlobalId: generateIfcGuid(),
Name: 'Exterior Wall East',
Description: 'Load-bearing exterior wall',
PredefinedType: 'SOLIDWALL',
});
// Place the wall in the ground floor
model.containInSpatialStructure(storeys[1].expressID, wall.expressID);
// Add properties to the wall
const pset = createPropertySet(model, 'Pset_WallCommon', [
{ name: 'IsExternal', value: true },
{ name: 'LoadBearing', value: true },
{ name: 'FireRating', value: 'REI90' },
{ name: 'ThermalTransmittance', value: 0.18, type: 'IFCREAL' },
{ name: 'AcousticRating', value: '52 dB' },
]);
assignPropertySet(model, pset.expressID, [wall.expressID]);
// Export to STEP file
const stepOutput = model.toStep();
console.log(stepOutput.substring(0, 500)); // PreviewNavigate the project hierarchy.
import { flattenSpatialTree } from '@ifc-factory/core';
const tree = model.getSpatialTree();
// Recursive tree print
function printTree(node: any, indent = 0) {
const prefix = ' '.repeat(indent);
const name = node.entity.Name ?? '(unnamed)';
console.log(`${prefix}${node.entity.type}: ${name} [#${node.entity.expressID}]`);
for (const child of node.children) {
printTree(child, indent + 1);
}
}
printTree(tree);
// Output:
// IfcProject: Residential Tower [#1]
// IfcSite: Amsterdam Noord [#2]
// IfcBuilding: Tower A [#3]
// IfcBuildingStorey: Basement [#4]
// IfcBuildingStorey: Ground Floor [#5]
// IfcBuildingStorey: Floor 1 [#6]
// ...
// Flatten to array for iteration
const allNodes = flattenSpatialTree(tree);
for (const node of allNodes) {
const elements = model.getContainedElements(node.entity.expressID);
console.log(`${node.entity.Name}: ${elements.length} elements`);
}Read an IFC file, modify it, and save.
import { IfcModel, createPropertySet, assignPropertySet } from '@ifc-factory/core';
import { readFileSync, writeFileSync } from 'node:fs';
// Parse
const source = readFileSync('input.ifc', 'utf-8');
const model = IfcModel.fromStep(source);
// Modify: add a property set to all walls
const walls = model.getAllOfType('IfcWall');
const pset = createPropertySet(model, 'Pset_Custom', [
{ name: 'LastModifiedBy', value: 'Ifc-Factory Script' },
{ name: 'ModificationDate', value: new Date().toISOString() },
]);
assignPropertySet(model, pset.expressID, walls.map(w => w.expressID));
// Write
const output = model.toStep();
writeFileSync('output.ifc', output);
console.log(`Wrote ${model.size} entities to output.ifc`);import { IfcModel } from '@ifc-factory/core';
import { validateModel, detectSchemaVersion } from '@ifc-factory/ifc-utils';
import { readFileSync } from 'node:fs';
const source = readFileSync('model.ifc', 'utf-8');
// Check schema version before parsing
const version = detectSchemaVersion(source);
console.log(`Schema: ${version}`); // 'IFC4X3', 'IFC4', 'IFC2X3', etc.
// Parse and validate
const model = IfcModel.fromStep(source);
const issues = validateModel(model);
const errors = issues.filter(i => i.severity === 'error');
const warnings = issues.filter(i => i.severity === 'warning');
console.log(`Errors: ${errors.length}, Warnings: ${warnings.length}`);
for (const issue of issues) {
console.log(`[${issue.severity.toUpperCase()}] ${issue.message}`);
}- Tutorials — Detailed walkthroughs for common scenarios
- Architecture — Understand how the library works internally
- API Reference — Complete function and class reference
- Dutch Compliance — BBL/BENG/Aerius property sets for Dutch projects
- IFC Concepts — Background on IFC and the STEP format
Ifc-Factory
Getting Started
Concepts
Packages
API & Reference
Development