build123d: The Algebraic Engine for CAD-as-Code

How a Python framework rejected fluent APIs and embraced operator overloading to turn physical manufacturing into a standard software pipeline.

8 min read • View on GitHub • More from gumyr

A heavy, tangled iron chain resting on a wooden workbench next to a set of pristine, modular metal blocks being neatly stacked by drafting calipers. Represents the transition from messy, chained operations to clean, modular components.
The shift from fluent method chaining to algebraic context managers allows developers to use standard Python features for physical design.

build123d also depends on OCP, and I agree with the prior comment that compiling to WASM is not trivial... I think this is a nice goal but is a huge project unto itself that would require more time than I am willing to devote to it.

jdegenstein, Contributor · Compile to wasm · Issue #946
Key Takeaways

The Fluent API Trap

For years, the dream of "CAD-as-code"—defining physical objects through text rather than a graphical user interface—has been hampered by API design. The most prominent Python-based precursor, CadQuery, relied heavily on a "fluent" API. This meant executing geometric operations through long chains of method calls.

While method chaining provided a concise way to represent sequential operations, it created significant friction. Massive, tangled chains broke standard IDE features like Pylance and IntelliSense. Simple control flow, such as loops or conditional logic, became cumbersome when forced into a chained structure. Worst of all, it isolated CAD scripts from normal Python logic, making them difficult to debug or unit test.

# The Fluent API Approach (CadQuery style)
result = cq.Workplane("front").box(2, 2, 2).faces(">Z").cylinder(1, 1)

# The Algebraic Approach (build123d style)
with BuildPart() as my_part:
    box = Box(2, 2, 2)
    with BuildSketch(box.faces().sort_by(Axis.Z)[-1]):
        Circle(1)
    extrude(amount=1)

The Algebraic Rebellion

build123d was built to solve this syntax trap by treating 3D topology like standard Python objects. The core innovation is the rejection of the fluent API in favor of algebraic context managers and operator overloading.

By using with BuildPart():, the framework manages state implicitly. When a developer needs to perform geometric booleans—unions, subtractions, intersections—they use standard Python operators like += and -=. Location transformations are handled by the @ operator. This turns 3D modeling into basic arithmetic, allowing developers to build complex parametric designs using the full power of the Python language.

The Algebraic Assembly: Context managers and overloaded operators map directly to C++ boolean operations in the CAD kernel.

Taming the Open Cascade Leviathan

Beneath the elegant Python syntax, build123d is commanding a leviathan: Open Cascade (OCP). This massive C++ boundary representation (BREP) kernel is the same engine that powers professional tools like FreeCAD and SolidWorks. Wrapping such a complex C++ library in Python is notoriously difficult, often leading to unpredictable behavior or performance degradation.

A massive, complicated clockwork engine buried underground connected by a single thick cable to a simple, elegant set of telegraph keys above ground. Visualizes the abstraction layer between the high-level Python API and the low-level C++ kernel.
build123d acts as a high-level bridge, hiding the complexity of the Open Cascade C++ kernel behind standard Python arithmetic.

To tame this complexity, the build123d maintainers rely on strict enforcement of modern software engineering practices. The repository mandates a highly rigorous linting process (enforcing a 9.5/10 pylint score) and runs automated benchmarks on every push across macOS, Ubuntu, and Windows. This ensures that the overhead of the Python wrappers doesn't degrade performance during complex geometry calculations.

Portrait of jdegenstein, contributor to build123d.

Unit Testing the Physical World

By fully integrating with standard Python, build123d enables a profound shift in how hardware is designed: unit testing for physical objects. Because 3D topologies are just Python objects, hardware engineers can write pytest suites to assert volume, clearance, and tolerances.

A close-up of a mechanical inspector's gauge pressing against a precisely machined gear, with a small paper tag hanging from the gear showing a cleanly printed checkmark. Represents CI/CD and unit testing applied to physical geometry.
By treating physical dimensions as standard variables, hardware objects can be subjected to automated CI/CD pipelines.

Imagine a workflow where a pull request for a 3D-printed part is automatically rejected because the new geometry fails a volume or clearance benchmark. This is not theoretical; it is a workflow that build123d's architecture explicitly supports, bringing the rigor of continuous integration to the physical manufacturing pipeline.

The Code-CAD Ecosystem

The CAD-as-code landscape is diverse, but build123d occupies a specific niche. It differs fundamentally from tools like OpenSCAD, which uses its own functional DSL and Constructive Solid Geometry (CSG) math, and CadQuery, which uses Python but traps it in a fluent API.

Featurebuild123dCadQueryOpenSCAD
Modeling ParadigmAlgebraic (Context Managers, Operators)Fluent (Method Chaining)Functional DSL
Underlying KernelOpen Cascade (C++)Open Cascade (C++)CGAL / OpenCSG
Geometry TypeBoundary Representation (BREP)Boundary Representation (BREP)Constructive Solid Geometry (CSG)
Python Ecosystem IntegrationFull (Loops, IDE autocomplete, Pytest)Limited (Chains break IDE tooling)None (Requires separate Python wrapper)