# Ifc Impl Format Transcoding

> Use when converting an IFC model between encodings (SPF .ifc, ifcXML, ifcJSON, ifcZIP) and the result must stay faithful, and when deciding which on-disk format to pick for a given exchange. Prevents confusing a format transcode with a schema-version migration, expecting STEP #id numbers to survive a round-trip, treating ifcJSON as a guaranteed lossless format, and assuming DERIVE or INVERSE attributes are lost in conversion. Covers the format comparison matrix, the EXPRESS schema as the single canonical model, SPF to ifcXML conversion (ISO 10303-28 plus the Part 28 configuration file), SPF or ifcXML to ifcJSON (provisional), ifcZIP wrapping, what is and is not preserved, and the transcoding vs version-migration vs geometry-export split. Keywords: IFC format conversion, transcoding, SPF to ifcXML, ifc to json, ifcXML, ifcJSON, ifcZIP, ISO 10303-28, Part 28 configuration file, lossless, round-trip, "which IFC format", "convert ifc file", "ifc file too big", "json instead of ifc", "lost data after conversion",

- Skill: `impertio-studio/ifc-impl-format-transcoding` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add impertio-studio/ifc-impl-format-transcoding`
- Raw SKILL.md: https://api.skillmd.com/api/skills/impertio-studio/ifc-impl-format-transcoding/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- License: MIT
- Author: Impertio-Studio (https://skillmd.com/u/impertio-studio)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/impertio-studio/ifc-impl-format-transcoding

---


# IFC Format Transcoding

Convert an IFC model between its on-disk encodings without losing data, and pick
the right encoding for an exchange. The governing fact : IFC is one EXPRESS schema
with several derived encodings. Transcoding re-renders the SAME model population in
a different encoding. It NEVER changes the schema version and NEVER changes the
geometry.

This skill is encoding-level. For a schema-version change (IFC2x3 to IFC4) see
`ifc-impl-version-migration` ; that is migration, not transcoding. For the encoding
syntax itself see `ifc-syntax-step-physical-file`, `ifc-syntax-ifcxml`,
`ifc-syntax-ifcjson`.

## Quick Reference

### The four encodings

| Format | Extension | MIME type | ISO standard | Size vs SPF | Status |
|--------|-----------|-----------|--------------|-------------|--------|
| SPF / STEP | `.ifc` | `application/x-step` | ISO 10303-21 | 100% | Official |
| ifcXML | `.ifcXML` | `application/xml` | ISO 10303-28 | 113% | Official |
| ifcZIP | `.ifcZIP` | `application/zip` | none | 17% | Official |
| ifcJSON | `.json` | `application/json` | none | 148% | Provisional / Candidate |

Sizes are the official buildingSMART figures (SPF = 100%). ifcZIP 17% is the
compressed size of whichever text payload it wraps.

### Core rules

- The EXPRESS schema is the single canonical model. ALWAYS treat a transcode as
  "read the EXPRESS population, re-render it" : the model is the invariant, the
  file bytes are not.
- ALWAYS keep the schema version fixed across a transcode. SPF IFC4 transcodes to
  ifcXML IFC4, NEVER to ifcXML IFC2x3. Changing the version is migration.
- DERIVE and INVERSE attributes are NEVER serialized in ANY encoding, so a
  transcode can NEVER lose them. They are recomputed by the reader.
- NEVER promise a lossless ifcJSON round-trip. ifcJSON is provisional ; round-trip
  is a design goal, not a guarantee.
- ifcZIP is pure compression. Wrapping and unwrapping is ALWAYS lossless.

## Decision Trees

### Is this transcoding or migration

```
Does the schema version change (FILE_SCHEMA value differs) ?
├─ NO  : same version, different encoding
│        -> TRANSCODING. This skill. Re-render the EXPRESS population.
└─ YES : IFC2x3 to IFC4, IFC4 to IFC4.3, etc.
         -> SCHEMA-VERSION MIGRATION, not transcoding.
            Entities are renamed/removed/added. See ifc-impl-version-migration.
            (A migration may ALSO change encoding ; do the two steps separately.)
```

### Which target encoding to pick

```
What is the priority for this exchange ?
├─ Widest compatibility, smallest text  -> SPF (.ifc). The default.
├─ XML toolchain (XSLT, XPath, XSD validation), schema validation -> ifcXML
├─ Web / JavaScript app, REST API, JSON-native consumer          -> ifcJSON
│   (accept provisional status and weaker tooling)
└─ Transfer or storage where size dominates -> ifcZIP
    (wraps an SPF or ifcXML payload ; decompress before parsing)
```

### Is a given transcode lossless

```
Which pair ?
├─ SPF  <-> ifcXML   : lossless AT THE MODEL LEVEL (ISO 10303-28 + Part 28
│                      config). File-level details (#id, layout) are NOT kept.
├─ * <-> ifcZIP      : ALWAYS lossless (pure compression of an unchanged payload).
└─ SPF/ifcXML <-> ifcJSON : model-level fidelity NOT guaranteed (provisional
                            format). Verify against the converter before relying
                            on a round-trip.
```

## Patterns

### Pattern 1 : the canonical-model mental model

A transcode is always two steps over the EXPRESS schema as the pivot:

```
source encoding  --parse-->  EXPRESS population (entities, explicit attributes,
                                                 references)  --render-->  target encoding
```

ALWAYS think in terms of the EXPRESS population, never byte-for-byte text. Two
files in two encodings are "the same model" when they encode the same population
of entities and explicit attribute values. ALWAYS confirm `FILE_SCHEMA` (SPF) or
the schema namespace (ifcXML) or `schemaIdentifier` (ifcJSON) matches before and
after.

### Pattern 2 : SPF to ifcXML and back

ifcXML is governed by ISO 10303-28, not ISO 10303-21. The EXPRESS-to-XSD mapping
is not deterministic on its own : a published **Part 28 configuration file**, one
per IFC schema version, pins the mapping. ALWAYS use the configuration file that
matches the model's schema version.

This pair is lossless at the model level : both encode the same EXPRESS population.
What does NOT survive:

- STEP `#id` integers become XML `id` / `ref` / `href` strings. The numbering is
  NOT preserved.
- Positional attributes become named XML elements or attributes.
- An unset attribute (`$` in SPF) becomes an absent element in ifcXML.
- Comments and exact text layout are lost.

ALWAYS validate the model population after the transcode, NEVER diff the raw bytes.

### Pattern 3 : transcoding to and from ifcJSON

ifcJSON is a Provisional / Candidate format with no ISO standard, synchronized to
IFC4.3 (and usable for IFC4). It is 148% of SPF size. The cross-reference key is
the entity `globalId` (a UUID) inside a `{"type": ..., "ref": ...}` object,
replacing the SPF `#id`.

ALWAYS state the provisional status when proposing ifcJSON. NEVER promise a
lossless SPF to ifcJSON to SPF round-trip : the ifcJSON specification lists
round-trip as a design goal, and converters may apply options (compact
formatting, inverse handling) that change output. ALWAYS verify a round-trip
against the actual converter for the target IFC version before depending on it.

### Pattern 4 : ifcZIP wrapping

ifcZIP is a plain ZIP archive. ALWAYS apply these rules:

- The archive uses PKZip 2.04g (DEFLATE) compression. NEVER use encryption,
  Unicode archive features, or deflate64 : those break compatibility.
- The archive MUST contain exactly ONE `.ifc` file OR exactly one `.ifcXML` file
  in its main directory. NEVER place multiple model files in one ifcZIP.
- Wrapping and unwrapping change nothing in the payload : ifcZIP is ALWAYS
  lossless. To "transcode" an ifcZIP, unwrap it, transcode the payload, re-wrap.

### Pattern 5 : what is at risk, what is safe

ALWAYS preserve, by an explicit strategy, the items genuinely at risk:

| At risk in a transcode | Why | Mitigation |
|------------------------|-----|------------|
| Instance identifiers (`#id` vs `id` vs `globalId`) | each encoding uses its own scheme | rely on `GlobalId` (the IfcRoot UUID), never on `#id` |
| Order of unordered aggregates (`SET`, `BAG`) | unordered by definition | NEVER depend on member order of a SET or BAG |
| Header metadata | not modeled identically across encodings | re-state author, timestamp, view definition after transcode |
| Comments | not part of the model | accept loss ; move notes into model entities |
| `IfcReal` numeric formatting | text representation differs | compare values numerically, not as strings |

NEVER-at-risk (because never serialized in any encoding): DERIVE attributes and
INVERSE attributes. A transcode cannot lose them ; the reader recomputes them.

### Pattern 6 : transcoding vs migration vs geometry export

Three different operations are routinely confused:

| Operation | Changes | Routes to |
|-----------|---------|-----------|
| Transcoding | encoding only (SPF to ifcXML to ifcJSON) | THIS skill |
| Schema-version migration | schema version (IFC2x3 to IFC4) ; entities renamed | `ifc-impl-version-migration` |
| Geometry / format export | derived output (meshes, glTF, OBJ, COLLADA) | not IFC at all ; `ifc-impl-geometry-extraction` |

Library tools mirror this split : an `ifcpatch` Migrate recipe performs
schema-version migration ; an `IfcConvert`-style tool performs geometry export.
ALWAYS name the operation correctly before choosing a tool. This skill does NOT
teach library APIs ; for tool selection see `ifc-impl-library-selection`.

## Reference Links

- `references/methods.md` : per-format facts, version coverage, the ISO 10303-28
  and Part 28 detail, the preservation matrix.
- `references/examples.md` : the same model in SPF, ifcXML, and ifcJSON, plus
  worked transcode walk-throughs.
- `references/anti-patterns.md` : the conversion failure modes and why each fails.

### Related skills

- `ifc-syntax-step-physical-file` : the SPF `.ifc` encoding (ISO 10303-21).
- `ifc-syntax-ifcxml` : the ifcXML encoding (ISO 10303-28, Part 28 config).
- `ifc-syntax-ifcjson` : the provisional ifcJSON encoding.
- `ifc-impl-version-migration` : schema-version change, NOT transcoding.
- `ifc-impl-library-selection` : choosing a library or tool for a conversion.
- `ifc-errors-encoding-issues` : string-escape and character-encoding failures.

### Verified sources

All format facts verified 2026-05-20 via WebFetch against the buildingSMART
sources in `SOURCES.md` : the IFC file-formats page, the ifcXML Implementation
Guide v2.0, implementation agreement CV-2x3-154 (ifcZIP), and the
`buildingsmart-community/ifcJSON` repository.

