Skip to main content

woodwright

A semantic CAD library for woodworking. You describe furniture the way a woodworker thinks about it: boards and rods with named sides, and the joints between them. woodwright works out the joinery, the cut sizes and where every part goes, and produces 3D models (STEP, STL), drawings (SVG, PDF) and cut lists.

It is built on build123d. This is an early alpha: the API will still change.

A chair drawn by woodwright The chair taken apart, showing its tenons and mortises
A chair with mortise-and-tenon joints, assembled and exploded: projects.chair in the example library. Every tenon and mortise is derived from the joints between the parts.
A workbench drawn by woodwright The workbench taken apart, showing its laps, tusk tenons and dowels
A knock-down workbench after Rex Krueger's Quick Stack Workbench, assembled and exploded: projects.workbench. Laminated legs and rails, half-dovetailed laps, stretchers held by tapered dowel tusks, a desk of beams on edge and a tray that turns over into a flat top. This is only a rough approximation with different dimensions: get Rex's plans for the real thing with detailed instructions if you want to build one.
The parts sheet of the table: an exploded view with numbered parts and a parts list The shop drawing of the table's front and back aprons, with dimensioned tenons
Plans to build from, generated in one PDF: the plans of a table (projects.table). A cover, contents, a description, dimensioned shop drawings (the assembly, its parts exploded and numbered, and a sheet for each part with every tenon and mortise dimensioned, identical parts drawn once), the cut list, and the code the plans were made from. Above: the parts and the front and back aprons.

Getting started without programming

You don't need to know Python to try woodwright: one small program, uv, installs it with everything it needs, and you then type a few commands.

  1. Open a terminal: Terminal on macOS (in Applications / Utilities), PowerShell on Windows (from the Start menu), any terminal on Linux.

  2. Install uv by pasting this line into it and pressing Enter.

    • macOS and Linux:
      curl -LsSf https://astral.sh/uv/install.sh | sh
      
    • Windows:
      powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
      

    Then close the terminal and open a new one.

  3. List the examples, from single joints to whole projects (the first run downloads Python and woodwright, which takes a minute):

    uvx --python 3.14 woodwright list
    
  4. Export one, e.g. a small cabinet door:

    uvx --python 3.14 woodwright export projects.cabinet_door
    

    This makes a folder output/projects/cabinet_door in the folder the terminal is in (your home folder, unless you moved with cd). In it:

    • plans.pdf – the plans in one PDF, to print or send: a cover, contents, all the drawings below, the cut list and the code they were made from;
    • cut_list.txt – each part with its size and its cuts (tenons, mortises, grooves...), a plain text file;
    • drawings/ – shop drawings to build from, open them in a web browser and print them (A4): a sheet for each part with its views, dimensions in mm and its cuts numbered and described; the whole thing with its overall size; its parts numbered on an exploded view, with a parts list;
    • .svg pictures of the whole thing, an exploded view and each part;
    • .stl 3D models of the whole thing and each part – open them in any online STL viewer;
    • assembled.step – the 3D model for CAD programs such as the free FreeCAD, which opens the .stl files too.
  5. Make your own: in a plain text editor (TextEdit set to plain text, Notepad, ...) write a file my_door.py with the sizes you want:

    from woodwright.examples import projects
    
    door = projects.cabinet_door(height=700, width=450)
    

    and export it, in the folder where you saved it:

    uvx --python 3.14 woodwright export my_door.py
    

    The results are in output/my_door/door. To describe your piece in its plans, add a text below, for example:

    door.description = """
        A glazed door for a wall cabinet.
    
        - **Wood**: oak, planed all round.
        - Fit the glass after the finish.
        """
    

    (headings start with #, list items with - or 1.). What each example can change (sizes, stock thickness...) is listed at the top of its code in the example library; copying an example's code into your file is the way on to your own designs.

To update woodwright later, write woodwright@latest instead of woodwright once. If you use an AI coding assistant (e.g. Claude Code), you can also ask it to do all of this for you.

Installation

pip install woodwright  # or: uv add woodwright

Requires Python 3.14. The woodwright command lists and exports the examples and your own design files (woodwright --help). Source: https://github.com/bzamecnik/woodwright

Quickstart

A rail tenoned into a stile. You give the design dimensions and the joint; the tenon, the mortise, the rail's cut length and its placement are derived.

from pathlib import Path

import woodwright as ww
from woodwright.export import export_model

oak = ww.Stock.board(thickness=20, species="oak")

frame = ww.Assembly("corner", root_location=ww.orient(right_end=ww.UP, back_edge=ww.RIGHT))
stile = frame.add(ww.Board("stile", oak, length=600, width=60))
rail = frame.add(ww.Board("rail", oak, length=300, width=60))  # shoulder to shoulder
frame.join(ww.MortiseTenon(tenon=rail.left_end, mortise=stile.back_edge))

model = frame.resolve()
print(model.cut_list())
export_model(model, Path("output/corner"))  # STEP, STL, SVG views, drawings, PDF, cut list
stile  600 x 60 x 20 mm  oak
       - mortise 50 x 8 mm, 42 deep, in stile.back_edge
rail   340 x 60 x 20 mm  oak
       - tenon 50 x 8 mm, 40 long, on rail.left_end

What's there so far:

  • Stock: boards, and round rods (dowels, pegs, rungs, round legs).
  • Cuts: grooves, dados and rabbets (through or stopped), mortises, slot mortises, tenons (haunched, mitred, chamfered, multiple side by side or across the thickness, wedged), tongues, dovetail tongues and laps, chamfers, mitres (across the face, the edge, or along the grain), tapers; holes (through, blind, counterbored, countersunk, tapered), round tenons (tapered, chamfered, with a kerf for a wedge), end chamfers, round tapers and flats on rods.
  • Joints: butt (also turned at an angle); dado, rabbet, groove and tongue and groove housings (also stopped); mortise and tenon (blind, through, stub, haunched, mitred, with mitred shoulders, multiple, wedged, tusk, pinned, drawbored); loose tenons and loose tongues; bridles (L and T); half laps (plain, dovetailed, mitred), cross laps, mitred face tenons; box joints; sliding, through, half-blind, mitred-corner and blind mitred dovetails; mitre corners and splices, keyed mitres (straight, dovetailed or slanted keys across the corner), splined mitres (along the corner or the mitre line, through or stopped); butterfly keys across a crack or the joint of two boards; table-top buttons; round tenons and whole rods in holes (blind, through, tapered, wedged, into square or round stock); dowels; screws (clearance and pilot holes, countersunk or counterbored).

Example library

woodwright.examples holds over 140 examples, from single cuts through joints to projects: a try square, a mallet, a bookshelf, a dovetailed drawer with a bottom, a dining table, a side table, a chair, a stool and a step stool on round legs wedged through their seats, a towel rail, a coat rack with pegs, ledged and frame-and-panel doors, a small glazed cabinet door, a knock-down workbench after Rex Krueger's Quick Stack (get his plans for the real thing).

woodwright list
woodwright export projects.chair --out output

The design ideas are in docs/vision.md and docs/plan.md.

Development

Install the environment and dependencies:

uv sync
pre-commit install  # ruff lint + format on commit

Optionally, for notebooks with an interactive 3D viewer:

uv sync --group notebook
uv run jupyter lab

Run the tests and the linters:

uv run pytest
uv run ruff format
uv run ruff check --fix

License

MIT License.

Credits

  • Ideas and guidance: Bohumír Zámečník
  • Most of the implementation: Claude Code (Opus 5.5)

Metadata

Release files for woodwright 0.8.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 woodwright 0.8.0
File Size Uploaded Provenance
woodwright-0.8.0.tar.gz 428.8 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 581.0 kB

Release files / woodwright-0.8.0.tar.gz

Download URL woodwright-0.8.0.tar.gz
Size 428.8 kB
Tags Source
SHA-256 checksum
How to use checksums
622343f20d4a10fdb40afa6fa3aba02d6e48c2554c46c9f2b898e356d3b8998e
BLAKE2b-256 checksum
How to use checksums
30cf6a9ad64a55ebfad1a17b797310bfed8700449301f75c16f618e31644de95
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / woodwright-0.8.0-py3-none-any.whl

Download URL woodwright-0.8.0-py3-none-any.whl
Size 152.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3a0892fbc900d19c4b63dbefb76f7f9e484987fa509007d1e325022ba77a5436
BLAKE2b-256 checksum
How to use checksums
9db9150410b0527858e66a434d673296ae6f59556f3a445cc03d248e394afc67
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for woodwright 0.8.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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