Skip to main content

onescad

Bundle an OpenSCAD model into one self-contained, Customizer-ready .scad file.

uvx onescad model.scad -o dist/model.scad

The bundle renders identically to the source, keeps the Customizer's parameters, groups, and widgets, and carries the license text of every file it takes code from. Python 3.11 or newer; no runtime dependencies.

Usage

onescad INPUT -o OUTPUT [-L DIR]... [--verify] [--version]
Option Meaning
INPUT The model's .scad file.
-o, --output The bundle to write. Parent directories are created.
-L, --library DIR A directory to search for include and use; repeatable.
--verify Render the source and the bundle with openscad and compare them.
--version Print the version.

Warnings print to stderr as onescad: warning: <message>. Errors print as onescad: <message>.

Exit code Meaning
0 The bundle was written (and verified, with --verify).
1 The bundle could not be built or verified.
2 Usage error.

Search path

include and use are resolved in this order: the including file's directory, each -L directory, then each OPENSCADPATH entry. OpenSCAD also searches the user and built-in library directories; onescad does not, so a bundle is the same on every machine. Put those libraries on -L or OPENSCADPATH. A missing file is an error that lists the directories searched.

What gets bundled

The output has these parts, in order:

  1. A header of // comments:
    • the onescad version, marked as generated;
    • the source path relative to its git root, the remote as an https URL, and the commit, with +dirty when tracked files have uncommitted changes (omitted outside a git work tree with a commit);
    • the main file's leading comment;
    • the fonts named by font= strings, the files read by import() or surface(), and a note naming the presets file, when they apply;
    • for each license file covering code that was kept, its directory and its text verbatim. The license file is the nearest LICENSE*, LICENCE*, or COPYING* in an ancestor directory of each source file.
  2. The Customizer parameters, hoisted to the top.
  3. A /* [Hidden] */ marker, so nothing after it appears in the Customizer.
  4. Each used file's definitions, dependencies first, each preceded by a // onescad: <path> marker and the file's leading comment.
  5. The main file, with its included files spliced in.

The output has no timestamps, so the same input gives byte-identical output.

Definitions that the model never reaches are dropped. A definition is renamed (name__1) when keeping its name would capture a different reference, as when a library wraps a builtin it later overrides.

Presets

If model.json sits next to model.scad, onescad copies it verbatim to the output's name with a .json extension (dist/model.json for -o dist/model.scad). OpenSCAD loads presets only from a .json beside the .scad, so keep the two together. A warning names each preset key that is not a Customizer parameter of the bundle.

Verification

--verify needs openscad on PATH. It compares the source with the bundle on:

  • the CSG of the default parameters and of every preset;
  • the ECHO lines, after undoing renames;
  • the Customizer parameter set (-o x.param, ignoring title).

The bundle renders with OPENSCADPATH unset and an empty HOME, which proves it is self-contained. text() fonts are not compared. Verifying needs an OpenSCAD that can export param (the 2026.09 snapshots do; 2021.01 is untested).

Limitations

  • The Customizer is emulated, not run. A model whose parameter assignment reads a name before that name's first assignment cannot be hoisted; onescad stops with an error.
  • A top-level $ variable in a used file, conflicting definitions that cannot be renamed, and a rename that would split a call's possible targets are errors.
  • A top-level variable in a used file is evaluated once in the bundle, not on every call as OpenSCAD does; onescad warns.
  • import() and surface() still read their files at render time; onescad warns and lists them in the header. Relative paths then resolve against wherever the bundle is rendered.
  • Fonts are not embedded; the header lists those that font= names.
  • A model's license text appears in the header only when a license file covers its source. onescad warns about each source file with none.

License

MIT. See LICENSE. Bundles carry the licenses of their inputs; check them before redistributing.

Metadata

Release files for onescad 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for onescad 0.1.0
File Size Uploaded
onescad-0.1.0.tar.gz 334.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for onescad 0.1.0
File Interpreter ABI Platform
onescad-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 370.4 kB

Release files / onescad-0.1.0.tar.gz

Download URL onescad-0.1.0.tar.gz
Size 334.2 kB
Tags Source
SHA-256 checksum
How to use checksums
5d803c53e5cc903aacb50ff4faae1e3a210a12dc508173c077fe0c185216f072
BLAKE2b-256 checksum
How to use checksums
44bf843ab806eacc1291af43883ac4c39f0793b897bbd3205b9e796b626e3519
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release files / onescad-0.1.0-py3-none-any.whl

Download URL onescad-0.1.0-py3-none-any.whl
Size 36.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
47a6f65a23d70ac171d8722626670b04243759f04250481821e953401dd94685
BLAKE2b-256 checksum
How to use checksums
a2813634e76c676f806e15bf977d2497af7a122f3990b999de9cd6d5f7e56977
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.0

2 release files

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page