Skip to content

JavaScript and TypeScript ​

@openbim/ifc is the WebAssembly build of the IFC core (openbim-ifc-wasm), published to npm with TypeScript declarations. It is tested under Node; a tested browser and bundler build is not published yet.

bash
npm install @openbim/ifc

The package is CommonJS: const { IfcModel } = require("@openbim/ifc");, or a default import from ES modules.

The binding exposes the record model over STEP: parse, read and edit attributes, and write. Domain views such as property sets or the spatial tree (#123), ifcXML, validation and checked transactions (#244) are not bound yet; use the Rust crates for those. The browser and bundler build is #40.

Read, edit and write ​

js
const model = IfcModel.parse(bytes); // bytes: the .ifc file as a Uint8Array
const schema = model.schema; // "IFC4"

for (const wall of model.idsOfType("IfcWall")) {
  const name = model.attribute(wall, 2); // { kind: "text", value: "Wall" }
  model.setAttribute(wall, 2, { kind: "text", value: `${name.value} (checked)` });
}

const out = model.write(); // a Uint8Array, ready to save

Entity ids are bigint, because IFC ids exceed JavaScript's safe integer range in real files. Attribute values use a tagged encoding that keeps every distinction STEP makes: $ from *, .U. from .F., an integer from a real, and a typed wrapper such as IFCLENGTHMEASURE(2.5) from its payload. A file read and written back is unchanged.

Every failure throws an IfcError whose code is one of the IfcErrorCode values below, the same codes the Python and C bindings use.

API ​

Generated from the #[wasm_bindgen] exports in crates/openbim-ifc-wasm/src/model.rs.

MemberThrows IfcErrorDescription
new IfcModel()An empty model.
IfcModel.parse(bytes: Uint8Array): IfcModelyesParse a STEP (.ifc) file from its bytes.
model.write(): Uint8ArrayyesSerialize as STEP bytes.
model.size: numberNumber of entities.
model.schema: string | undefinedThe first FILE_SCHEMA token, e.g. "IFC4", or undefined.
model.diagnostics(): string[]Non-fatal problems found while reading.
model.ids(): bigint[]Every entity id (bigint), in file order.
model.idsOfType(typeName: string): bigint[]Ids of every entity of exactly typeName, case-insensitive.
model.idsOfTypeIncludingSubtypes(typeName: string): bigint[]yesIds of every entity of typeName or any subtype, per the file's declared schema: IfcWall also finds IFCWALLSTANDARDCASE.
model.typeOf(id: bigint): stringyesThe upper-case type name of entity id.
model.attributes(id: bigint): IfcValue[]yesEvery attribute of entity id, as tagged values.
model.attribute(id: bigint, slot: number): IfcValueyesAttribute index of entity id, as a tagged value.
model.setAttribute(id: bigint, slot: number, value: IfcValue): IfcValueyesSet attribute index of entity id; returns the previous value.
model.add(typeName: string, attributes: IfcValue[]): bigintyesAppend an entity; returns its id (bigint).
model.remove(id: bigint): voidyesRemove entity id, leaving references to it dangling.
model.danglingReferences(): [bigint, bigint][]Every [from, to] pair (bigints) where to does not exist.

Attribute values and error codes are typed by the package's .d.ts:

ts
/** One IFC attribute value, in the lossless tagged encoding (ADR 0013). */
export type IfcValue =
  | { kind: "null" }
  | { kind: "derived" }
  | { kind: "bool"; value: boolean }
  | { kind: "unknown" }
  | { kind: "integer"; value: bigint }
  | { kind: "real"; value: number }
  | { kind: "text"; value: string }
  | { kind: "binary"; value: string }
  | { kind: "enum"; value: string }
  | { kind: "ref"; id: bigint }
  | { kind: "list"; items: IfcValue[] }
  | { kind: "typed"; type: string; value: IfcValue };

/** The `code` of an `IfcError`. */
export type IfcErrorCode =
  | "parse"
  | "write"
  | "missing-entity"
  | "invalid-value"
  | "out-of-range"
  | "unsupported-schema";

Released under the AGPL-3.0-or-later licence. ISO and CEN standards material is not redistributed.