Library / SDK
stepcode/stepcode avatar
stepcode/stepcode

STEPcode: generating C++ and Python from EXPRESS schemas

STEPcode (formerly NIST's STEP Class Library) is used with IFC, STEP, and other standards that utilize the technologies of ISO10303 (STEP). It generates C++ and Python from EXPRESS (10303-11) schemas. The code is capable of reading and writing STEP Part 21 exchange files. It also utilizes Parts 22 and 23 (SDAI and its C++ binding).

533 stars136 forksCNOASSERTION

At a glance

What is it?
STEPcode reads ISO 10303-11 EXPRESS schemas and generates code that reads and writes STEP Part 21 files conforming to them, with experimental Python support alongside the C++ output. It is a code generator for a thirty year old standard, and its real value is that the schema, not the implementation, defines the data.
Who is it for?
STEPcode suits a team that has to interoperate with a STEP based standard, such as IFC, and wants its data model driven by the published EXPRESS schema rather than by hand written serialisation code, and it does not suit a project that only needs to read one file once, since the setup cost is a schema, a generator and a build.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 25 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A generator where the schema is the source of truth

The question STEPcode answers is specific: how do you get a program that reads and writes a file conforming to a published data standard without writing the serialisation code by hand?

The answer is that ISO 10303-11 defines EXPRESS, a formal schema language, and a Part 21 file is a physical encoding of an instance of one of those schemas. If you have the schema, everything else is mechanical. STEPcode reads EXPRESS schemas and generates C++ source code that can read and write Part 21 files conforming to that schema. In addition to C++, it includes experimental support for Python.

That is the whole idea, and it is the reason this project still matters. A Part 21 file is a tagged text format where each instance carries a type name and a list of attributes, and the mapping from that text to your program's data structures is entirely determined by the schema. Write it by hand and you are transcribing hundreds of entity definitions. Generate it and the schema does the transcription.

The project description widens the scope usefully. STEPcode is used with IFC, STEP and other standards that use ISO 10303 technologies. It also uses Parts 22 and 23, which are SDAI and its C++ binding, so this is not only a text file parser but an implementation of the schema-driven data modelling layer above it.

The primary language of the repository is listed as C, which fits: the core and the generated code are C and C++, and the Python output is a separate, still experimental path.

The name change that says what the project is

The readme's history section is short and it explains the project's shape better than any feature list could.

It was renamed in April and May 2012. It was formerly known as the STEP Class Libraries, SCL for short, and it was renamed because the name was not accurate: the class libraries make up only a part of the code. STEPcode is the current name, and the description makes the same point: it generates C++ and Python from EXPRESS schemas and it can read and write STEP Part 21 exchange files.

The origin is also stated. The STEP Class Library was originally created at NIST in the 90s, and much of the work to update it has been done by the developers of BRL-CAD, which is the open source solid modelling and CAD system. That lineage explains a lot about the codebase. It is a thirty year old C and C++ project that has been carried forward by a community with a very specific need, rather than a library designed for a general market.

The version in the readme header is v0.8, which is worth pausing on given the age. The listed releases are v0.8.2 with the note one more STEP, from 2023-09-25, and v0.8.1 with the note A small STEP, from 2022-10-02. Those release notes are almost a parody of the project's relationship with ISO 10303, and the current default branch is develop rather than master, which is the usual sign that the released tags lag the working branch.

The readme also points at a NEWS file for information on changes version by version, and at the INSTALL file for building and testing, which is where anyone actually starting should look, since the readme itself does not give build commands.

The build is CMake and CTest, with coverage wired in

The repository layout is that of a native C and C++ project with a modern test harness.

There is a CMakeLists.txt at the root, a cmake/ directory, and a CTestConfig.cmake. The CTest integration is more than a single file: ctest_matrix.cmake and run_ctest.cmake sit alongside it, which suggests the test suite is run across a matrix of configurations rather than one build, and lcov.cmake is present for coverage collection. The .github/ directory with a build.yml workflow badge points at GitHub Actions running the same thing.

The source is in src/, the public headers in include/, and the schema and test data in data/. There is a doc/ directory, an example/ directory, and a misc/ directory that also holds the astyle configuration used for code formatting.

The single example directory is example/ap203min/, which tells you the reference case. AP203 is one of the application protocols, a well known schema for mechanical parts and assemblies, and the min variant is the minimal one. It is the shape of the thing in one name: you point the generator at a schema, and you get a C++ class library that reads and writes files for it.

The intent for a new user is that the build produces both libraries and executables, since the readme refers to the wiki page about the libraries and executables for more detail, and the CONTRIBUTING.md and INTENT.md files are there alongside a ChangeLog. The ChangeLog and NEWS files sitting next to each other is itself a signal: this is a project that records its history carefully, which is what you want from a code generator whose output you are going to trust for years.

The coding standards are unusually specific

A generated code base is only as maintainable as its formatting, and STEPcode's readme has a whole section on it.

The source has been reformatted with astyle, and contributors are asked to match the current formatting. The main points are compact, Java style brackets, indents of 4 spaces, no tab characters, LF line endings rather than CRLF, brackets around single line conditionals, spaces inside parentheses and around operators, the return type on the same line as the function name unless that is too long, and doxygen style comments.

The bracket example is given in the readme, and it is specific enough to be worth looking at.

C
    if( a == 3 ) {
        c = 5;
        function( a, b );
    } else {
        somefunc( );
    }

Two details in that snippet are the kind that tell you the project is machine generated and machine checked. The space inside the empty parentheses of somefunc( ) is astyle's output, not a typo. And the compact bracket style with the brace on the same line as the condition is what you get when the same formatter runs over every generated and hand written file in the tree.

For anyone sending a patch, the practical instruction is in the last lines of the section: if in doubt about a large patch, run astyle with the config file misc/astyle.cfg. Astyle itself is downloaded from a SourceForge project, which dates the tooling assumption.

This is the kind of convention document that is invisible when it is working and infuriating when it is missing. A project whose output is a large volume of machine written C++ that people then have to read, patch and regenerate needs exactly this, and the fact that the readme spends this much room on formatting rather than on features tells you where the project's attention has been.

Where STEPcode is the wrong tool

There are two situations where this is the wrong choice, and one situation where it is the only choice.

The wrong choice, first. If you need to read one STEP file once, or if you need to read a file whose schema is not published as EXPRESS, then generating a class library is a lot of machinery. There are lighter approaches to Part 21 parsing, and the cost of the schema-driven route includes obtaining the right schema, running the generator, wiring the generated code into your build, and then owning a code generator's output forever. That cost is worth paying when you are committing to a standard, and it is pure overhead for a one off.

The second wrong choice is if you need a language binding that does not exist. The C++ output is the mature path. The Python support is described as experimental in the readme, and that word should be taken at face value. If your team wants to work in Python, you are adopting an experimental code path in a project whose versioning is still at 0.8, and you should plan on the possibility of regeneration changing your API.

The limitation that follows from all of this is that the schema dialect matters, and the readme does not enumerate what is supported. ISO 10303 has EXPRESS, EXPRESS-C, and a long tail of application protocols, and Part 21 has a set of encoding rules with a few corners. The readme mentions that the tool uses Parts 22 and 23, SDAI and its C++ binding, and it points to the wiki for detail, but it does not tell you which EXPRESS constructs are handled, which Part 21 features are covered, or what happens on an entity the schema defines but the generator does not support. For a project where the schema is the contract, that is the question to resolve before you start, and it means reading the wiki and the INSTALL file rather than the readme.

There is also a licensing wrinkle worth naming. The readme says the licence details are in the COPYING file and summarises it as 3-clause BSD, while the licence field on the repository is listed as a custom one that GitHub cannot classify. Both statements come from the project, and they do not obviously agree. The COPYING file is the authority, and anyone who needs certainty about redistribution in a commercial product should read it and take advice rather than rely on either summary.

On the alternative, the difference in approach against a hand written parser or a schema library from another ecosystem is the same one that separates most code generators from hand written code. A hand written parser for a Part 21 file gives you exactly the entities you thought of, written in the idiom of your project, with no build step and no generated code to reconcile with upstream. What it does not give you is the guarantee that you handled every entity the schema defines, and the cost of that gap shows up the first time a file contains an entity your code skipped. STEPcode removes that class of bug by construction, at the price of a generated layer that lives in your repository and has to be regenerated when the schema changes.

For a team whose product is defined by a published standard, that trade is usually worth making, because the standard changes and the generator follows it. For a team with a handful of known files, it is not.

Editorial conclusion

STEPcode suits a team that has to interoperate with a STEP based standard, such as IFC, and wants its data model driven by the published EXPRESS schema rather than by hand written serialisation code, and it does not suit a project that only needs to read one file once, since the setup cost is a schema, a generator and a build. Before you commit, check which EXPRESS dialect and Part 21 features your target standard actually uses, because the readme does not enumerate them, and read the COPYING file yourself, since the README summarises the licence as 3-clause BSD while the licence field on the repository is listed as a custom one that GitHub cannot classify.

Frequently asked questions

What is STEPcode?

STEPcode reads ISO 10303-11 EXPRESS schemas and generates C++ source code that can read and write Part 21 files conforming to that schema, with experimental support for Python in addition to C++.

What is the difference between STEPcode and the old STEP Class Library?

They are the same project. It was renamed in April and May 2012 from STEP Class Libraries because that name was not accurate, since the class libraries make up only a part of the code.

Is the Python support in STEPcode production ready?

The readme describes the Python support as experimental. The C++ output is the mature path, and the C++ binding of SDAI, Part 23, is also used.

How do I build STEPcode?

The readme does not give the build commands itself and points you to the INSTALL file for building and testing, and to the wiki page about the libraries and executables. The repository uses CMake and CTest, with GitHub Actions running the build workflow.

What licence is STEPcode under?

The readme says the licence details are in the COPYING file and summarises it as 3-clause BSD, while the licence field on the repository is listed as a custom one that GitHub cannot classify. Read the COPYING file for the terms that actually apply.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. stepcode/stepcode on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/stepcode-stepcode.svg)](https://hysenlabs.com/projects/stepcode-stepcode)

Was this useful?