OpenSCAD Packer
Pack an OpenSCAD entry file and all its use/include dependencies into a single self-contained .scad file.
Instead of distributing a project as a directory tree of files (and requiring recipients to have the same libraries installed), OpenSCAD Packer bundles everything into one file. It uses tree-shaking to include only the functions and modules that are actually called — directly or transitively — so the output stays lean even when pulling from large libraries.
Why?
3D printing model sites such as Printables, Thingiverse, and MakerWorld support parametric models: the site parses an uploaded .scad file, exposes its configurable parameters to the user (via OpenSCAD's Customizer), and renders a download-ready 3MF or STL with the chosen values — no local OpenSCAD installation required.
The catch: these sites only accept a single .scad file. A design that pulls in BOSL2, NopSCADlib, or any other library cannot be uploaded as-is. The creator must somehow inline all dependencies into one file before uploading.
OpenSCAD Packer automates that. It resolves every use and include, tree-shakes out the unused code, and writes a single self-contained file ready to upload.
OpenSCAD's Customizer reads magic comments in the .scad source to build its parameter UI — for example, width = 20; // [1:100] creates a slider, and /* [Section Name] */ creates a collapsible group. By default, OpenSCAD Packer preserves comments from the entry file so these annotations survive packing and the Customizer UI works as expected on the destination site. Pass --no-preserve-comments to strip them if you prefer a leaner output.
How it works
use <lib.scad>— the library is parsed and only the reachable function and module definitions are inlined. Variables and top-level calls are discarded (matching OpenSCAD's ownusesemantics).include <file.scad>— function and module definitions are tree-shaken into the output; top-level assignments and module calls are always preserved (they affect variables and rendered geometry).- Libraries that cannot be found cause an immediate error with a clear message. Pass extra search directories with
-Lif your libraries live outside the standard OpenSCAD path.
Installation
Requires Python 3.11+ and uv.
uv tool install openscad-packer
This installs the openscad-packer command globally via uv's tool isolation.
Alternatively, add it as a dependency in your own uv project:
uv add openscad-packer
Usage
openscad-packer pack [OPTIONS] INPUT
Arguments:
INPUT Entry .scad file to pack.
Options:
-o, --output PATH Output file. Defaults to stdout.
-L, --library-path PATH Extra library search directory (repeatable).
--preserve-comments/--no-preserve-comments
Preserve entry-file comments in output (default: on).
--help
Examples
Pack to a file:
openscad-packer pack my_model.scad -o my_model_packed.scad
Pack to stdout (useful for piping or inspection):
openscad-packer pack my_model.scad
Point to libraries that are not on the standard OpenSCAD path:
openscad-packer pack my_model.scad -o packed.scad -L ./vendor/BOSL2 -L ./vendor/NopSCADlib
Library search order
For each use/include path, the tool searches in this order:
- Directories supplied via
-L(in the order given) - The directory containing the file that references the library
- Directories in the
OPENSCADPATHenvironment variable - The platform default:
~/Documents/OpenSCAD/libraries
Developer guide
Prerequisites
- Python 3.11 or later
- uv — used for environment management and running the tool
Clone and set up
git clone https://github.com/NascentMaker/OpenSCAD-Packer.git
cd OpenSCAD-Packer
uv sync --dev
uv sync --dev creates a virtual environment at .venv/, installs all runtime dependencies, and installs the dev group (pytest, pytest-cov, coverage).
Note:
uv syncwithout--devomits the dev group and will not install pytest.
Run the CLI locally
uv run openscad-packer pack entry.scad -o packed.scad
Run the tests
uv run pytest
Branch coverage is enabled automatically. After the run, an HTML report is written to htmlcov/index.html.
To run a subset of tests:
uv run pytest -v -k "tree_shak"
Project structure
openscad_packer/
cli.py # click entry point — pack command
packer.py # Packer class: collect phase + assemble phase
shaker.py # AST walker, tree-shaking, reachability analysis
resolver.py # Library path resolution
tests/
conftest.py
test_cli.py
test_packer.py
test_resolver.py
test_shaker.py
Building a distribution
uv build
This produces a wheel and sdist in dist/. To publish to PyPI:
uv publish
License
OpenSCAD Packer is released under the GNU Affero General Public License v3.0.
Release files for openscad-packer 2026.6.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| openscad_packer-2026.6.6.tar.gz | 49.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| openscad_packer-2026.6.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 75.6 kB
Release files / openscad_packer-2026.6.6.tar.gz
| Download URL | openscad_packer-2026.6.6.tar.gz |
|---|---|
| Size | 49.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
499070310ceaa678f0291013ffcde28ebdf7fab0dba57ccad435063a204f4525
|
|
BLAKE2b-256 checksum How to use checksums |
a9c610540f39050afcf6f5db609cbdabf52f9522c42b066e81d5b8bb3923d32a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / openscad_packer-2026.6.6-py3-none-any.whl
| Download URL | openscad_packer-2026.6.6-py3-none-any.whl |
|---|---|
| Size | 25.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
83bdabb0416523795070bb860096ad6e5033e2af5622c37e1baa9952bffbad65
|
|
BLAKE2b-256 checksum How to use checksums |
26fe4d1662f368e6585325e52b82f8d3af45269c22afd4c53d3b1901ffe8408b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|