Partwright Beta
Open editor →

How Partwright works

A complete guide to the editor, viewport, painting, sessions, exports, and the in-browser AI assistant. Skim the table of contents below, or jump straight to a section.

New See what’s shipped recently →

What is Partwright?

Partwright is a browser-based parametric CAD tool powered by manifold-3d (compiled to WebAssembly). It runs entirely in your browser — no server, no account, no data leaving your machine.

You write code that constructs 3D geometry. The result renders live in the viewport, and you can save iterations as versions, paint colored regions for multi-material 3D printing, and export to 3MF, STL, OBJ, or GLB.

Partwright supports several modeling languages and engines: JavaScript (default, using the manifold-3d mesh API), OpenSCAD (standard .scad syntax via WASM), BREP (true OpenCASCADE solids via replicad, with selective fillets/chamfers and STEP export), and voxel (build from cubes, with image and .vox import). Switch between them with the language toggle in the toolbar — your in-progress code in each language is preserved as a draft, and every saved version remembers the language it was authored in, so a single session can hold mixed versions. See Modeling engines below for the full rundown.

The editor & status indicator

The left pane is a CodeMirror editor with syntax highlighting for both JavaScript and OpenSCAD. In JavaScript mode, your code receives an api object and must return a Manifold object. In OpenSCAD mode, use standard SCAD syntax (no return needed).

Status indicator — Just above the editor, a small badge reports engine state:
  • Ready — idle, geometry rendered successfully
  • Running… / Loading… — code or WASM is in flight
  • Error — compilation or runtime error; click for full message

Auto-render — The ⏸ Auto button toggles live re-rendering as you type. When paused, a manual ▶ Run button appears. Useful when iterating on heavy geometry that you don't want re-running on every keystroke.

Building geometry

JavaScript: Start with primitives like Manifold.cube(), Manifold.cylinder(), or Manifold.sphere(). Combine them with boolean operations: .add() (union), .subtract(), .intersect(). Add 3D lettering with api.text() (a solid) or api.textSection() (a 2D profile to extrude yourself).

OpenSCAD: Use standard primitives cube(), cylinder(), sphere() with boolean operations difference(), union(), intersection(). The text() primitive is supported (Liberation Sans font family).

Coordinate system: Right-handed, Z-up. The XY plane is the ground, Z points up. Units are arbitrary — use a consistent scale (millimetres are common for 3D printing).

Modeling engines & languages

Beyond plain JavaScript and OpenSCAD, Partwright reaches several geometry kernels — each is lazy-loaded the first time you use it, so you only pay for what you reach for:
  • JavaScript / manifold-3d (default) — Fast mesh booleans plus warp, levelSet, smoothing, and curve helpers.
  • OpenSCAD — Standard .scad with the BOSL2 library (threaded rods, gears, rounded cuboids, and more).
  • BREP (replicad / OpenCASCADE) — True boundary-representation solids with selective edge fillets and chamfers, exact surfaces, and STEP import + export. Use it two ways: call api.BREP.* inside a JavaScript session for one exact feature, or switch the whole session to the BREP language. It adds cone, torus, revolve, shell, and linear/circular patterns.
  • Voxel — Model from a grid of cubes. Import an image as voxels or load a .vox file, paint individual voxels, and surface the result with rounded edges; includes cylinder, mirror, translate, and hollow operations.

Signed-distance fields (api.sdf): Inside a JavaScript session, build organic and lattice geometry from SDF primitives and combinators — including a TPMS family (gyroid and friends), polarRepeat / repeatN tiling, and smooth boolean blends.

Customizer parameters (api.params): Declare tunable parameters in your code and adjust them from a parameter panel — no need to edit the source to dial a design in.

Use the ? language-help button in the toolbar for a quick reference on whichever language is active.

Quick example

const { Manifold } = api;

// Create a box and subtract a cylinder
const box = Manifold.cube([20, 20, 10], true);
const hole = Manifold.cylinder(12, 4, 4);

return box.subtract(hole);

Tabs in the right pane

The right pane is divided into tabs. Each one offers a different view of the current version:
  • Interactive — Live 3D viewport. Drag to orbit, scroll to zoom, right-drag to pan.
  • Gallery — Grid of saved versions. Click any thumbnail to load that version into the editor.
  • Images — Attach reference photos or renderings (file upload or paste URL). Each image gets a label (Front / Right / Back / Left / Top / Perspective) for ordering and reference.
  • Diff — Side-by-side comparison between any two versions: code on the left and right, plus a stats delta bar (volume, dimensions, manifold status).
  • Notes — Per-session free-text log. Use it to capture requirements, decisions, and feedback as the design evolves.

Viewport tools

Buttons in the viewport overlay (top-right of the Interactive tab):
  • Grid — Toggle the XY ground plane grid.
  • Dimensions — Toggle the bounding-box overlay with X / Y / Z extents.
  • Orbit lock — Freeze camera rotation. Useful while painting, measuring, or annotating.
  • Measure — Click to drop point 1, drag to point 2; the distance shows as a 3D label. Click elsewhere to clear. Orbit lock engages automatically.
  • Cross-section — Toggle a horizontal clipping plane. A Z slider appears; everything above the plane is hidden and the cut face renders in red.
  • Annotate — Draw freehand strokes or drop pinned text labels on the model. Annotations are saved per version and survive export to .partwright.json.
  • Paint — Color regions of the model for multi-material printing (full details below).
  • Palette — Manage your printer's filament slots: define, reorder, and reset the colors, build a palette from a photo (auto-detected dominant colors or a click-to-eyedrop pick), and constrain painting to those slots. Slot-aware paint regions map onto a printer's AMS slots and export to 3MF in slot order.
  • Quality — Tune curvature quality and simplify or enhance the model's triangle count in one panel. Drag a slider or type an exact target, then "Apply"; "Save as version" bakes the result into a new version and "Reset" restores full detail.
  • Resize — Scale the model along X / Y / Z with independent or uniform sliders, a typeable exact size, and an optional "preserve colors" pass. A live preview updates as you drag; Apply saves a new version.
  • Reset view — Return the camera to its default framing. A zoom-out limit keeps the model from shrinking away into the distance.
  • Surface — Apply a surface modifier: fuzzy skin (randomized printed-texture noise), smooth (round out facets), voxelize (convert the surface to a cube grid), or one of the fabric textures — V-strand knit, cable knit, waffle stitch, fur / velvet, and woven fabric, wrapped over the surface via UV unwrapping (GPU-accelerated where supported). A mesh-detail slider trades triangle count for fidelity. Apply a modifier to the whole model or to a click-selected region (additive multi-region selection, with a color-sensitivity control). Preview before committing; each apply creates an undoable new version.

The Quality, Resize, Surface, and Relief panels share the same conventions — drag them by the header to reposition, and they stay on-screen on mobile.

Painting & color regions

Click the Paint button in the viewport overlay to open the color panel. Pick a tool, pick a color, and click the model. Painted regions are saved with the version and exported as native color in 3MF (for slicers like Bambu Studio), as vertex color in OBJ + MTL, and as vertex color in GLB.

Paint tools:
  • Bucket (flood-fill) — Click a face; paint propagates across connected neighbours, either by geometry (within an angle tolerance you set with a slider, 0° = "coplanar only" up to 180° = "whole connected mesh") or by color (every region sharing the clicked color). Hover for a translucent preview before committing.
  • Brush — Click and drag to paint individual triangles. Release to commit the region. A Wrap tolerance slider (0–180°, default 90°) keeps a stroke from bleeding across sharp edges — paint crosses an edge only when the two faces bend by no more than the tolerance.
  • Slab — Pick an X/Y/Z axis, then drag a range along the model surface; every triangle whose centroid falls inside the slab gets painted. A translucent cuboid previews the slab extent.
  • Shape — Paint everything inside a positionable, rotatable, scalable 3D shape (box, sphere, cylinder, or cone).
  • Replace — Click the mesh to pick a source color, then swap it for the active color across every matching region at once.
  • Image — Project an image onto the surface as color regions: click to stamp it where you point (with a hover preview and rotation), or use smooth mode to subdivide the footprint so the picture conforms to curvature. Alpha-channel flood fill drops the background, and SVG inputs stamp at full vector quality.

Region management: The panel lists every painted region with its color and triangle count. Use Undo / Redo to step through history, Hide / Show to toggle visibility (exports still include the colors), and Clear to remove all regions. The Paint button shows a badge with the live region count. The code editor stays fully editable while you paint — saved versions are your rollback path if you want to step back.

Filament slots: Paint from a filament palette (the 🧵 Palette pill) and each region is tagged with a stable printer slot — recolor a slot and every region on it updates at once. A “Colors in this model” view tags colors on- or off-palette and lets you Replace, Merge, or auto-match them to the nearest slot, and an over-budget badge warns when a model uses more colors than your palette has slots.

Export formats and color: 3MF carries painted regions as native materials in filament-slot order (recommended for printing). OBJ + MTL and GLB carry per-triangle vertex colors. STL is geometry-only — no color.

Relief Studio (image → relief)

The Relief Studio turns a 2D image into a printable relief — a HueForge-style workflow for layered, multi-color prints. A guided wizard walks you from image to model:
  • Inputs — Drop in a photo, or use a flat-color tile, a silhouette tile, or an imported SVG. Crop and preprocess the image, and pick a background to drop out.
  • Relief modes — Smooth height-map relief, or stepped relief with Z-banded walls that print faithfully on a single nozzle (with an invert-heights toggle). A live 3D preview updates as you tune.
  • Finishing — Add a tile chamfer and one or more freely-positioned keychain holes, then send the result into a session as a painted model with a color-swap guide.

Typeable sliders let values exceed the visual range, and the studio remembers recent imports with their settings.

Sharing & multi-part sessions

Shareable links — Generate a link that encodes your model entirely in the URL (client-side, nothing uploaded). Anyone who opens it sees a read-only preview and can Fork it into their own editable session.

Multiple parts per session — A session can hold several separate objects, listed in the Parts rail with a geometry preview for each. Select multiple parts (the checkboxes) to bulk-delete them or merge them — either combining into a new part or replacing the selection with one merged part. Imported meshes can be added as new parts too.

Sessions & versions

A session is a container for a single design — its code, saved versions, notes, attached images, and annotations. All session data lives in your browser's IndexedDB; nothing is uploaded.

Creating a session — Click + New Session in the session bar, or start typing in the editor (Partwright auto-creates one). A session can hold mixed JS + SCAD versions — flipping the language toggle preserves your draft in each language and saved versions remember the engine they were authored in.

Saving versions — Click 💾 Save to snapshot the current code, geometry, annotations, and color regions. Versions auto-name as v1, v2, v3… and a save only happens if something actually changed. Use the ◀ / ▶ arrows in the session bar (or the version dropdown) to step through history; the URL updates to ?session=<id>&v=<n> so browser back/forward work as expected.

Gallery — Each version tile shows a thumbnail, label, geometry stats (volume, dimensions, manifold status), color-region swatches, and the version's notes. Click a tile to load.

Notes — Per-session free text in the Notes tab. Add, edit, and delete entries; timestamps are recorded for each.

Managing sessions — Click Sessions… in the toolbar to open the session list: rename, delete, export, or open any session. Empty sessions (no versions, no notes) are auto-cleaned when you move on.

Catalog & Ideas

Click ☰ Catalog in the toolbar to browse a gallery of premade models — twisted vase, retro rocket, chess rook, Christmas tree, desk organizer, spur gear, print-in-place fidgets, and more. Each tile shows a thumbnail, the language it's written in, and a short description. A search box and per-language filter pills narrow the gallery by keyword or modeling language, and curated groups (like Fidget Toys) lead the list. Click a tile to preview, then Import to load it as a fresh session — a great starting point for learning the API or remixing into your own designs.

The Ideas page (/ideas) is a separate collection of starter prompts and technique showcases. Clicking a tile populates the AI panel input — ready to send, or edit first. The same library is available inside the AI panel via the 💡 button.

Importing & exporting

Import — Open a .partwright.json session from another machine (or paste a URL that resolves to one), load raw .js / .scad code, or bring in a mesh (.stl) or a BREP solid (.step). When a session is already open, an import-target dialog lets you add the import as a new part, compose it into the current part, or start a new session. The Import dropdown also remembers your recent imports (with their settings) for one-click re-loading.

Photo → 3D (Self-Modeling Studio) — Import ▸ “Photo → 3D” turns a single photo into a model: generate a turntable of alternate angles with a Gemini image model (or upload them yourself), curate the tiles, then either carve a voxel model from the silhouettes or hand the angle set to the AI modeler. Cardinal / Isometric / Full presets choose how many views to use, and the studio remembers recent imports.

Multi-file OpenSCAD — If a .scad file pulls in its own include <…> / use <…> dependencies, Partwright detects the missing files and prompts you to supply them. Companion files get their own editable, syntax-highlighted tabs and are saved with the session.

Export — 3D model formats:
  • 3MF (recommended for printing) — Geometry plus native color regions, emitted in filament-slot order so the material index follows your AMS slots. Imports cleanly into Bambu Studio and other modern slicers.
  • OBJ — Geometry plus color via an MTL sidecar. Delivered as a ZIP — extract before importing into a slicer.
  • STL — Geometry only, no color. Universal slicer support.
  • GLB — Web/preview format with vertex colors. Good for embedding online, not read by slicers.
  • STEP — Exact BREP solids, available from BREP-language sessions. The CAD interchange format for downstream engineering tools.

Export — Project formats:
  • Session (.partwright.json) — All versions, notes, annotations, color regions, and attached images. Another Partwright user can import this and pick up where you left off. A dialog lets you choose whether to embed the thumbnail, notes, annotations, and color regions.
  • Code (raw) — Just the editor contents as plain .js or .scad.

The Export dropdown remembers recent exports so you can download the exact same blob again without re-running the code.

Quality settings & theme

Quality — Curvature quality lives in the viewport ○ Quality panel. Pick a preset (Ultra / Very High / High / Medium / Low) that controls how many segments approximate a circle, or choose Custom to type an exact count. Ultra (1024 segments) gives near-perfect curves for smooth final output, while lower presets render faster when you're iterating on heavy geometry. The preset only applies to curves that don't pass their own segment count, and the AI assistant honors it too. The starting default is set under Settings (the ⚙ icon).

Settings — The ⚙ icon opens Settings: tunable defaults across AI, renderer, import, and UI, each with a ? tooltip explaining what it controls (including the start-fresh / uninstall action).

Theme — Toggle Dark Mode in the toolbar to switch the entire UI, viewport background, and grid colors between dark and light. Your choice persists across sessions.

A note on AI costs & risk

Partwright is an experiment — a passion project exploring what happens when you put generative AI inside a 3D modeling tool, shared openly because I've found real joy in building it and hope others find value in it too. I've spent my own money on this and I'm not trying to make money from it.

That said: when you connect your own AI agent, it uses your API tokens. AI-driven CAD is genuinely hard and unpredictable — the agent might iterate many times before landing on something good (or give up trying). There are some guardrails in place to help limit runaway spend, but there's no guarantee they work perfectly in every situation. By connecting your own AI agent, you accept responsibility for any API costs incurred, regardless of output quality.

Go in eyes open, start with small experiments, and enjoy the ride.

AI assistant in the browser

Partwright includes a built-in AI assistant. It runs entirely from your browser: you choose a provider and (for cloud providers) paste your own API key, and every request goes directly from your browser to that provider — Partwright never sees the key or the conversation. Five providers are supported:
  • Anthropic — Claude (Haiku / Sonnet / Opus), with prompt caching. Keys look like sk-ant-….
  • OpenAI — GPT and reasoning (o-series / gpt-5) models.
  • Google Gemini — Gemini models, including thinking models with a reasoning box.
  • Custom (OpenAI-compatible) — Point at any self-hosted OpenAI-compatible endpoint (a llama.cpp server, vLLM, LM Studio, …) by setting its base URL and model. The API key is optional; turns are free at the API level.
  • Local (WebGPU) — Runs a model fully in your browser via WebLLM. No API key, no network traffic per turn; the weights download once into the browser cache (needs a WebGPU-capable browser).

Connecting:
  1. Click Connect AI (or the Use AI button) in the toolbar.
  2. Pick a provider and paste its API key — or choose Run a local model in your browser to download a WebGPU model instead.
  3. Partwright sends a tiny test request to verify a cloud key, then stores it in your browser's IndexedDB.
  4. The toolbar button changes to ✦ AI and the chat panel is ready. Each provider remembers its own selected model, so switching providers keeps your previous choice.

Recommended: use a workspace-scoped key with a monthly spend cap. Anyone who can run code in this page (browser extensions, devtools) can read the key.
What the assistant can do — The chat panel docks on the right. Type a request (or type / for a slash-command menu of quick actions), attach images for reference, or click Show AI to snapshot the isometric views and feed them to the model. The assistant can write and run code, save versions to the gallery, paint colored regions, and iterate until your design is right. A 👁 Review button asks a different provider/model to critique the current design, and a 🩺 Call Log shows recent provider API calls for diagnostics.

Thinking level — A 🧠 pill (off / low / medium / high) sets reasoning effort and maps to each provider's own thinking format; reasoning models that expose their chain of thought show it in a collapsible thinking box.

Auto-continue (♾) — When on, the agent keeps working across multiple turns until it explicitly signals completion, instead of stopping at every response boundary. Bounded by the iteration and spend caps. On by default in Standard and Full presets; remembered across reloads.

Toggles & guardrails: At the bottom of the panel are switches for auto-rendering snapshots, allowing the model to run code, allowing it to save versions, allowing it to paint, how many tool errors to silently retry, a per-turn iteration cap (4 / 16 / 32 / 64 / ∞), and a per-turn spend cap ($0.10 / $0.50 / $2 / $5 / $10 / $20 / ∞). Use presets — Minimal, Standard, Full — to flip whole bundles at once.

Costs & history: The panel shows a live cost meter. The ⚙ icon opens settings with lifetime token usage, estimated spend, when the key was added, and buttons to replace or disconnect it. Chat history is saved per session in IndexedDB; use Compact to summarize older turns and free up context when conversations get long.

Connecting an external AI agent

If you'd rather drive Partwright from Claude Code, ChatGPT, or another agent (instead of using the in-browser assistant), there are three common setups:
  • Claude in Chrome extension — Install the extension and Claude can control your active tab directly. Best for interactive sessions where you watch and steer.
  • Chrome DevTools MCP — Enable remote debugging in Chrome, then add the MCP server to your agent. Uses your existing browser session and cookies.
  • Playwright MCP — Launches a separate browser, no Chrome setup needed. Best for automated or headless workflows.

Once connected, the agent navigates to Partwright, reads /ai.md for the full API reference, then drives the app via the window.partwright console API to create sessions, run code, validate results, and save versions. The legacy window.mainifold alias still works for older prompts.

Try it with an external AI agent

Copy and paste this prompt into Claude Code, ChatGPT, or any AI agent with browser access to verify everything works end-to-end:
Read the AI agent instructions at https://8f71f272.mainifold.pages.dev/ai.md to understand how to use this tool.

Then navigate to https://8f71f272.mainifold.pages.dev/editor and use the window.partwright console API to:

1. Create a session called "Standard Lego Brick"
2. Build a standard 2x4 Lego brick (approximately 31.8mm x 15.8mm x 11.4mm with studs on top and hollow underside with tubes)
3. Save each major step as a version (e.g. v1 - base block, v2 - add studs, v3 - hollow underside with tubes)
4. Use assertions to verify each version is a valid manifold with maxComponents: 1
5. Give me a share link (partwright.getShareLink()) when done so I can open the design
The agent should read ai.md, create a named session, iterate through versions, and hand back a read-only share link for review.

Command palette & cheat sheet

Press Ctrl + K anywhere to open the command palette — a searchable list of every action: run, save, format, switch tabs, export (3MF / STL / OBJ / GLB), toggle the AI panel or diagnostic log, start or open a session, or jump to the catalog or this help page. Type to filter, / to choose, Enter to run, Esc to close.

Press ? (when you're not typing in a field) to pop up the full keyboard-shortcuts cheat sheet from anywhere — the same list as below.

Keyboard shortcuts

Shortcuts adapt to your operating system (⌘ on macOS, Ctrl elsewhere).

  • Ctrl + K — Open the command palette — search and run any action by name.
  • ? — Open this keyboard-shortcuts cheat sheet (when not typing in a field).
  • Ctrl + Z — Undo the last paint region or annotation stroke, depending on which tool is active. When the code editor is focused it uses its own built-in undo.
  • Ctrl + Shift + Z or Ctrl + Y — Redo the last undone paint region or annotation stroke.
  • Ctrl + S — Save the current code, geometry, paint regions, and annotations as a new version in the active session.
  • Shift + Alt + F — Reformat the code in the editor.
  • Shift + Alt + F — Format the code in the editor.
  • Escape — Close the open dropdown, modal, paint or annotate panel, cross-section overlay, or exit the guided tour.
  • Enter / — Next step during the guided tour.
  • — Previous step during the guided tour.
  • Ctrl + Enter — Save the current notes textarea.
  • Enter in input modals (e.g. Connect AI, Import Preview) — Confirm.
New to the editor? Walk through the key features. Take the guided tour