This is a fork of OpenSCAD exploring one question: what should OpenSCAD expose so that a program — an agent, a studio, a build script — can understand the model it just rendered?
Today the answer is "a mesh". Everything semantic about a design — what its parts are, what a number means, which dimensions the author cared about — is thrown away at the door and reconstructed outside the binary, from geometry that no longer remembers any of it. The reconstruction is guesswork, it is expensive, and it fails silently. This fork asks what it costs to just say those things instead.
It is a working exploration, not a product and not a release. If you want stable OpenSCAD, use upstream — the original README follows below.
A faster interpreter. A script-evaluation performance series, backported
from Stocko-2073/openscad. On the
BOSL2-heavy benchmark model in the work journal, script evaluation went from
13.3s to 5.6s and total render time from 16.9s to 9.3s — every step of it
measured, and written down. This needs nothing from you: any .scad renders
faster, unchanged, with no include and no new syntax.
Four read-only channels, which answer questions about the model alongside the export:
| Flag | Answers |
|---|---|
--export-meta |
the dim() records — label, value, units, anchor points in export coordinates, source location — plus per-phase render timings |
--parts list |
the part() names, without rendering geometry at all. Exporting 3MF already writes one named object per part, which a slicer opens as a multi-part project; --parts off fuses them instead |
--export-metrics |
what the geometry backend measured — volume, area, bbox, centroid, genus, manifoldness — for the model and per part |
--export-clashes |
how each pair of parts stands: overlapping, touching, or clear, with the volume, area, or gap |
An extension must not change what a model means.
A .scad written against this build renders identically on a stock OpenSCAD, or
the premise is gone: a model nobody else can open is not a model. So the two
extensions that add language surface — the dim() and part() builtins — ship
with plain-OpenSCAD fallbacks, and a model includes them:
include <native-std.scad>
part("bracket") cube([10, 10, 4]);
dim("height", 20, units = "mm");On a stock OpenSCAD those definitions are what runs: part() is a passthrough
and dim() echoes. On this build they are waived and the builtins run instead,
so the same file yields structured records and named parts. The waiver is
explicit and scope-local — a part() of your own is never touched, and asking
for a channel whose name you have taken warns instead of silently recording
nothing. doc/native-extensions.md explains the mechanism.
On macOS 15 or later, Apple Silicon, there is a build already made: the
snapshot release,
rebuilt from main on every push. It is unsigned, so macOS will not open it
until the quarantine flag is cleared:
unzip OpenSCAD-macos15-arm64.zip
xattr -dr com.apple.quarantine OpenSCAD.app
The command line binary is inside the bundle, at
OpenSCAD.app/Contents/MacOS/OpenSCAD.
Otherwise build as upstream does (see below). Either way:
OPENSCADPATH=libraries \
openscad model.scad -o model.3mf \
--export-meta meta.json \
--export-metrics metrics.json
That writes a 3MF carrying one named object per part() — the split is the
default for 3MF, and --parts off turns it off — beside the dimension records
and the measurements.
To ask only what the parts are, without rendering any geometry:
openscad model.scad --parts list
- Not proposed upstream. These are design experiments; freezing an API by submitting it now would be premature. If any of it earns its place, the time to offer it is after it has been used in anger, not before.
- Command line first. The GUI builds and runs, but it is not extended: the channels are for programs, and nothing surfaces them in the application.
- No support, no stability promise. Flags and the record shapes may change.
- Based on upstream
121b48e8; upstream has moved on since.
The performance series is Stocko-2073's work,
backported here and rebased onto a newer upstream — see
doc/journals/2026-08-25-script-eval-performance.md, which records the
measurements, the leads that were dropped, and where each idea came from. The
guarded-dispatch idea the extensions rest on — recognising a definition and
letting a native implementation stand in for it — is theirs too.
Everything else in OpenSCAD is the work of the OpenSCAD authors, under the licence below.
doc/native-extensions.md— the channels, the fallback waiver, the diagnosticsdoc/journals/— work journals, including the full performance series
Everything below is upstream OpenSCAD's README, unchanged. The badges refer to upstream's CI, not this fork.
OpenSCAD is a software for creating solid 3D CAD objects. It is free software and available for Linux/UNIX, MS Windows and macOS.
Unlike most free software for creating 3D models (such as the famous application Blender), OpenSCAD focuses on the CAD aspects rather than the artistic aspects of 3D modeling. Thus this might be the application you are looking for when you are planning to create 3D models of machine parts but probably not the tool for creating computer-animated movies.
OpenSCAD is not an interactive modeler. Instead it is more like a 3D-compiler that reads a script file that describes the object and renders the 3D model from this script file (see examples below). This gives you, the designer, complete control over the modeling process and enables you to easily change any step in the modeling process or make designs that are defined by configurable parameters.
OpenSCAD provides two main modeling techniques: First there is constructive solid geometry (aka CSG) and second there is extrusion of 2D outlines. As the data exchange format for these 2D outlines Autocad DXF files are used. In addition to 2D paths for extrusion it is also possible to read design parameters from DXF files. Besides DXF files OpenSCAD can read and create 3D models in the STL and OFF file formats.
You can download the latest binaries of OpenSCAD at https://www.openscad.org/downloads.html. Install binaries as you would any other software.
When you open OpenSCAD, you'll see three frames within the window. The left frame is where you'll write code to model 3D objects. The right frame is where you'll see the 3D rendering of your model.
Let's make a tree! Type the following code into the left frame:
cylinder(h = 30, r = 8);Then render the 3D model by hitting F5. Now you can see a cylinder for the trunk in our tree. Now let's add the bushy/leafy part of the tree represented by a sphere. To do so, we will union a cylinder and a sphere.
union() {
cylinder(h = 30, r = 8);
sphere(20);
}But, it's not quite right! The bushy/leafy are around the base of the tree. We need to move the sphere up the z-axis.
union() {
cylinder(h = 30, r = 8);
translate([0, 0, 40]) sphere(20);
}And that's it! You made your first 3D model! There are other primitive shapes that you can combine with other set operations (union, intersection, difference) and transformations (rotate, scale, translate) to make complex models! Check out all the other language features in the OpenSCAD Manual.
Have a look at the OpenSCAD Homepage (https://www.openscad.org/documentation.html) for documentation.
To build OpenSCAD from source, follow the instructions for the platform applicable to you below.
To build OpenSCAD, you need some libraries and tools. The version numbers in brackets specify the versions which have been used for development. Other versions may or may not work as well.
If you're using a newer version of Ubuntu, you can install these libraries from aptitude. If you're using Mac, or an older Linux/BSD, there are build scripts that download and compile the libraries from source. Follow the instructions for the platform you're compiling on below.
- A C++ compiler supporting C++17
- cmake (3.5 ->)
- Qt (5.12 ->)
- QScintilla2 (2.9 ->)
- CGAL (5.4 ->)
- GMP (5.x)
- MPFR (3.x)
- boost (1.70 ->)
- OpenCSG (1.4.2 ->)
- GLEW (1.5.4 ->)
- Eigen (3.x)
- glib2 (2.x)
- fontconfig (2.10 -> )
- freetype2 (2.4 -> )
- harfbuzz (0.9.19 -> )
- libzip (0.10.1 -> )
- Bison (2.4 -> )
- Flex (2.5.35 -> )
- pkg-config (0.26 -> )
- double-conversion (2.0.1 -> )
For the test suite, additional requirements are:
- Python3 (3.8 -> )
- Ghostscript (10.x ->)
- Catch2 (3.0 ->)
Install git (https://git-scm.com/) onto your system. Then run a clone:
git clone https://github.com/openscad/openscad.git
This will download the latest sources into a directory named openscad.
To pull the various submodules (incl. the MCAD library), do the following:
cd openscad
git submodule update --init --recursive
You can create an issue to plan and discuss your change by visiting https://github.com/openscad/openscad/issues.
If you want to work on an existing issue and plan to contribute changes via a PR later, you can assign the issue to yourself by commenting:
/assign-me
in a comment on the issue.
Prerequisites:
- Xcode
- automake, libtool, cmake, pkg-config, wget, meson, python-packaging (we recommend installing these using Homebrew)
Install Dependencies:
After building dependencies using one of the following options, follow the instructions in the Compilation section.
-
From source
Run the script that sets up the environment variables:
source scripts/setenv-macos.shThen run the script to compile all the dependencies:
./scripts/macosx-build-dependencies.sh -
Homebrew (assumes Homebrew is already installed)
./scripts/macosx-build-homebrew.sh
First, make sure that you have git installed (often packaged as 'git-core' or 'scmgit'). Once you've cloned this git repository, download and install the dependency packages listed above using your system's package manager. A convenience script is provided that can help with this process on some systems:
sudo ./scripts/uni-get-dependencies.sh qt6
After installing dependencies, check their versions. You can run this script to help you:
./scripts/check-dependencies.sh
Take care that you don't have old local copies anywhere (/usr/local/).
If all dependencies are present and of a high enough version, skip ahead
to the Compilation instructions.
If some of your system dependency libraries are missing or old, then you
can download and build newer versions into $HOME/openscad_deps by
following this process. First, run the script that sets up the
environment variables.
source ./scripts/setenv-unibuild.sh
Then run the script to compile all the prerequisite libraries above:
./scripts/uni-build-dependencies.sh
Note that huge dependencies like gcc, qt, or glib2 are not included here, only the smaller ones (boost, CGAL, opencsg, etc). After the build, again check dependencies.
./scripts/check-dependencies.sh
After that, follow the Compilation instructions below.
A development Nix shell is included for local, incremental compilation.
OpenSCAD for Windows is usually cross-compiled from Linux. If you wish to attempt an MSVC build on Windows, please see this site: https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Building_on_Windows
MSVC build support has been added to OpenSCAD. For instructions on how to build it, refer to building with MSVC.
To cross-build, first make sure that you have all necessary dependencies
of the MXE project ( listed at https://mxe.cc/#requirements ). Don't install
MXE itself, the scripts below will do that for you under $HOME/openscad_deps/mxe
Then get your development tools installed to get GCC. Then after you've cloned this git repository, start a new clean bash shell and run the script that sets up the environment variables.
source ./scripts/setenv-mingw-xbuild.sh 64
Then run the script to download & compile all the prerequisite libraries above:
./scripts/mingw-x-build-dependencies.sh 64
Note that this process can take several hours, and tens of gigabytes of disk space, as it uses the https://mxe.cc system to cross-build many libraries. After it is complete, build OpenSCAD and package it to an installer:
./scripts/release-common.sh mingw64
For a 32-bit Windows cross-build, replace 64 with 32 in the above instructions.
We support building OpenSCAD headless for WebAssembly w/ Emscripten, using a premade Docker image built in openscad/openscad-wasm (which also has usage examples)
The following command creates build-web/openscad.wasm & build-web/openscad.js:
./scripts/wasm-base-docker-run.sh emcmake cmake -B build-web -DCMAKE_BUILD_TYPE=Debug -DEXPERIMENTAL=1
./scripts/wasm-base-docker-run.sh cmake --build build-web -j2openscad/openscad-playground uses this WASM build to provide a Web UI with a subset of features of OpenSCAD.
Note
With a debug build (-DCMAKE_BUILD_TYPE=Debug), you can set C++ breakpoints in Firefox and in Chrome (the latter needs an extension).
The following command creates build-node/openscad.js, which is executable (requires node):
./scripts/wasm-base-docker-run.sh emcmake cmake -B build-node -DWASM_BUILD_TYPE=node -DCMAKE_BUILD_TYPE=Debug -DEXPERIMENTAL=1
./scripts/wasm-base-docker-run.sh cmake --build build-node -j2
build-node/openscad.js --helpNote
With a debug build (-DCMAKE_BUILD_TYPE=Debug), you can set C++ breakpoints in VSCode + Node (needs an extension).
First, run cmake -B build -DEXPERIMENTAL=1 to generate a Makefile in the build folder.
Then run cmake --build build. Finally, on Linux you might run cmake --install build as root.
If you had problems compiling from source, raise a new issue in the issue tracker on the github page.
This site and it's subpages can also be helpful: https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Building_OpenSCAD_from_Sources
Once built, you can run tests with ctest from the build directory.
Note: Both cmake --build and ctest accepts a -j N argument for distributing the load over N parallel processes.
-
Install circleci-cli (you'll need an API key)
Note: we also use GitHub Workflows, but only to run tests on Windows (which we cross-build for in the Linux-based CircleCI workflows below). Also, act doesn't like our submodule setup anyway.
-
Run the CI jobs
# When "successful", these will fail to upload at the very end of the workflow. circleci local execute --job openscad-mxe-64bit circleci local execute --job openscad-mxe-32bit circleci local execute --job openscad-appimage-64bit
Note: openscad-macos can't be built locally.
-
If/when GCC gets randomly killed, give docker more RAM (e.g. 4GB per concurrent image you plan to run)
-
To debug the jobs more interactively, you can go the manual route (inspect .circleci/config.yml to get the actual docker image you need)
docker run --entrypoint=/bin/bash -it openscad/mxe-x86_64-gui:latest
Then once you get the console:
git clone https://github.com/%your username%/openscad.git workspace cd workspace git checkout %your branch% git submodule init git submodule update # Then execute the commands from .circleci/config.yml: # export NUMCPU=2 # ... # ./scripts/release-common.sh -snapshot -mingw64 -v "$OPENSCAD_VERSION"

