The Open Source framework for parametric 3D printable mechanical projects
- Open Source: Apache License 2.0
- Documentation: https://solid-node.readthedocs.io
$ pip install solid-node
$ solid new myprojectSee the docs.
This section is for contributors — humans and coding agents — who modify the framework in this repository. For using solid-node in your own mechanical project, see the documentation above.
Requirements: Python >= 3.10, OpenSCAD on the PATH, and Node.js >= 20 (only if you intend to rebuild the web viewer or the embeddable widget).
Clone with submodules (the docs embed the example V8-engine project):
$ git clone --recurse-submodules https://github.com/LibreSolid/solid-node.git
$ cd solid-nodeCreate a virtualenv and install the package in editable mode with the dev dependencies:
$ python -m venv .venv
$ source .venv/bin/activate
$ pip install -e ".[dev]"The solid CLI entrypoint (solid_node/cli.py) is now on the PATH of
the virtualenv.
The test suite is pytest, run from the repository root:
$ make test # equivalent to: pytest
$ pytest tests/test_builder_lifecycle.py # a single file
$ make lint # flake8 + black --check
$ make test-all # tox across supported Python versionsNotes:
- Rendering tests invoke the real
openscadbinary. On a headless machine, snapshot-related tests may needxvfb-run -a pytest .... tests/meta_project/together withtests/test_meta.pyis the end-to-end meta-project harness: it runs small real solid-node projects — both deliberately green and deliberately red fixtures — to prove the loading, rendering, andsolid testsubprocess paths. Use it when a change touches behavior that direct unit tests cannot establish; see docs/contributor-briefing.md for when and why.- Browser tests for the web viewer live with the application under
solid_node/viewers/web/.
solid_node/node/— the node tree (base, assembly, fusion, leaf, CAD backend adapters, operations)solid_node/manager/andsolid_node/cli.py— thesolidcommand: develop loop, test, snapshot, new, exportsolid_node/core/— build pipeline, loader, cachingsolid_node/test.py— mesh-oriented test cases and assertionssolid_node/viewers/— OpenSCAD snapshotter, web viewer (FastAPI + React/three.js), embeddable widgettests/— Python test suitedocs/— Sphinx documentation, architecture synthesis, ADRsopenspec/— OpenSpec change proposals and baseline specs
This repository is developed agentically and follows a strict spec-first discipline. Every behavioral change starts as an OpenSpec change proposal and is ratified before implementation. Drive-by edits, unrecorded redesigns, and "fix it first, document it later" are not how this project moves — this applies equally to human contributors and to coding agents operating autonomously.
Behavioral contracts live in openspec/specs/. Changes are proposed,
reviewed, implemented, and archived through the OpenSpec workflow
(OpenSpec, CLI v1.x; the repo's
openspec/config.yaml carries project context and rules):
- Propose — create a change under
openspec/changes/<name>/withproposal.md(why, what changes, capabilities, impact),design.md(how), andtasks.md(implementation steps). The change describes deltas against the current specs. - Review — the proposal is inspected and refined before any code is written. Specs describe observable behavior only; no aspirational requirements.
- Apply — implement the ratified proposal, task by task, TDD-style: red evidence first (a failing test that pins the contract), then the smallest change that satisfies it.
- Archive — when the change lands, its spec deltas are merged into
openspec/specs/and the change moves toopenspec/changes/archive/.
The .claude/commands/opsx/ and .claude/skills/openspec-*/ directories
encode this workflow for agents (propose, apply, archive, etc.);
humans can drive the same lifecycle with the openspec CLI directly.
Why the system is the way it is lives in docs/adrs/ (see
docs/adrs/README.md for the index and the full
discipline):
- One decision per ADR, numbered sequentially, filed under the subsystem it affects (NODE, BUILD, IPC, MATH, TEST-FRAMEWORK, VIEWER-WEB, EXPORT).
- Statuses flow
Proposed→Accepted; later ADRs may mark earlier onesSuperseded. Superseded ADRs stay in the log — they are the history that makes current decisions legible. - When an OpenSpec change carries an architectural shift, its ADR is written alongside the change and the architecture synthesis (docs/architecture.md) is updated as part of landing it.
Read order for orientation: architecture synthesis first
(docs/architecture.md), then the specs for exact observable behavior
(openspec/specs/), then an ADR when you need to know why
(docs/adrs/). The contributor briefing
(docs/contributor-briefing.md) adds
verification guidance: how to choose between direct pytest coverage and the
meta-project harness, and the red-first evidence principle.
Bug reports and pull requests are welcome at https://github.com/LibreSolid/solid-node — see CONTRIBUTING.rst and the development discipline above.