Tools: V select • L line • R rect • C circle • A arc • B bézier • S spline • Dim.
Shift-click to add to selection; drag empty space for rubber-band. Ctrl+Z undo.
Middle/right-drag to pan • scroll to zoom • 3D BG layers the model behind the sketch.
New sketch on…×
No face selected yet — right-click a face in the 3D view.
About SCAD+
SCAD+
Version 1.1.8
A browser-based 3D CAD editor and CSG engine. Write OpenSCAD-style code and see your models render instantly in the viewport.
OpenSCAD Compatibility: SCAD+ aims to be compatible with OpenSCAD, but not all functions and features are currently supported. Some standard OpenSCAD modules, functions, and language features may be missing or behave differently.
Built With
Manifold-3D — WASM-based CSG engine
Three.js — WebGL 3D rendering
CodeMirror 6 — Code editor
TypeScript + Vite — Build toolchain
Press ? to open the language reference.
SCAD Language Reference
3D Primitives
Function
Parameters
Description
cube
size, center, anchor, fillet, chamfer, edges, $fn
Box. size: number or [x,y,z]. Fillet > 0 convex, < 0 concave.
Variable-height extrusion. Height linearly interpolates from h_start at the lower end of axis ("x" or "y") to h_end at length mm further along. length defaults to the profile's bbox extent along axis. Equivalent to intersection(linear_extrude(max(h_start,h_end)) profile, tilted_ceiling). Optional chamfer / fillet args (with _top / _bot per-end overrides) are baked into the flat extrusion before the wedge cut, so the horizontal top + bottom edges round cleanly while the slanted slope of the wedge stays sharp. Wrapping a chamfer() module around tapered_extrude doesn't work — the chamfer's prismatic-shape assumption is violated by the tilted top.
Edge treatment
Generalized chamfer / fillet that wraps any 3D child. The child is sliced at the inner boundary of the edge zone to get its silhouette, and the zone is rebuilt as hull-stitched thin wafers following either a linear taper (chamfer) or a quarter-circle arc (fillet). The hull step gives smooth slanted sides — no staircase.
Function
Parameters
Description
chamfer
c, top=true, bottom=true, $fn
Linear taper on the top / bottom edges. c = chamfer size in mm.
fillet
r, top=true, bottom=true, $fn
Rounded quarter-arc on the top / bottom edges. r = fillet radius in mm. Higher $fn → smoother arc.
Scope. Only the top and bottom horizontal edges are touched — the square outline at zMax and zMin. Vertical side edges (e.g. the 4 corner edges of a cube) are not affected by these operators. For fully-rounded primitives use rounded_cube, or the fillet / chamfer args on cube / cylinder / pipe.
Silhouette complexity. The taper is built directly as a closed polyhedron for each topologically-disconnected island in the silhouette. For complex shapes where an offset would change topology (text, shapes with many thin features or holes that can collapse), the operator gracefully passes the child through unchanged rather than render a stepped approximation. If your chamfer(...) / fillet(...) wrapper seems to do nothing, that silhouette is too intricate for this algorithm and the shape is being returned as-is — add the bevel directly into the 2D profile or use a simpler shape.
2D Sketch Editor
Assignable curve-based profiles with an interactive 2D editor. Every gesture rewrites the SCAD source — the editor is a view of the text, not a separate model.
Entry
Action
How
+ New Sketch
Toolbar button opens a plane picker: XY / XZ / YZ create a sketch immediately; From Face… arms face-pick mode.
From Face…
After clicking the button, hover a face in the 3D viewport — the whole coplanar face highlights in amber. Left-click to pick the face; a sketch using that face's normal + point as origin is created and opens in the 2D editor.
Edit Sketch
Place the caret inside an existing sketchN = sketch(...); the toolbar button lights up showing the sketch name (e.g. Edit sketch2). Click to open.
Cursor switch
While the 2D editor is open, moving the text caret into a different sketchN auto-switches the editor to that sketch.
Sketch entity functions
Each returns a tagged record stored inside entities=[...]. Identity is preserved across edits so handles know where to go.
Function
Signature
Description
line
from=[x,y], to=[x,y]
Straight segment between two points.
rect
a=[x,y], b=[x,y]
Rectangle by two opposite corners.
arc
center=[x,y], r, start, end
Circular arc. Sweep is always CCW.
circle_entity
center=[x,y], r
Closed circle. Standalone closed path.
bezier
p0, c1, c2, p3
Cubic Bézier segment.
spline
points=[[x,y], …]
Smooth Catmull-Rom curve through all knots.
dim
from, to, value
Dimension annotation (no geometry; ignored by polygon()).
image
src, corner=[x,y], size=[w,h], opacity, rotation
Reference / tracing image. src is a localStorage key pointing to a data URL. Always rendered behind the sketch; ignored by polygon().
sketch
plane, origin, entities
Top-level wrapper. Assign to a variable and consume via polygon().
The walker links open segments by matching endpoints (order-independent). rect and circle_entity are standalone closed paths. EvenOdd fill handles multiple paths as holes automatically.
Keyboard shortcuts (inside the 2D editor)
Key
Tool
V
Select / drag anchors & bodies
L
Line (chains until Esc)
R
Rectangle (two-corner)
C
Circle (center + edge)
A
Arc (center, start, end)
B
Bézier (4 clicks)
S
Spline (Enter / dblclick to finish)
Shift+click
Add / remove from selection
drag empty space
Rubber-band selection
drag on selected
Translate the whole group (snapped to grid)
Ctrl+drag rect corner
Scale symmetrically about the rect center
Ctrl+drag image corner
Lock the image's native aspect ratio while resizing
Del / Backspace
Delete the current selection
Ctrl+Z / Ctrl+Shift+Z
Undo / redo (routed to code history)
Esc
Clear selection, cancel in-progress draw, or close editor
middle / right drag
Pan canvas
scroll wheel
Cursor-centered zoom
Toolbar extras
Button
Purpose
Auto Dim
Toggles a non-persistent overlay showing every entity's natural dimension — length for lines, width + height for rects, R⟨value⟩ radius for circles / arcs, L⟨length⟩ for bezier / spline, width + height for images. Each value is a click-editable inline input (Enter or blur to commit). Dims render on the outside of the shape using a centroid-based heuristic.
Dim
Persistent two-point dimension — inserts a dim(from, to, value) record that survives edits (selectable + deletable).
3D BG
Layers the 3D model behind the 2D canvas, aligned head-on to the sketch plane (orthographic). Hides the 3D grid / HUD / gizmo / outline. Pan + zoom stay in sync across both views; the model's opacity is set by the BG slider (0–100%).
Image
Import a reference image. The file is stored as a data URL in localStorage (key lives in src); the image is inserted as an image(...) entity at canvas center. Has four draggable corner handles (Ctrl+drag locks aspect). Opacity, rotation, and 90° rotate buttons are in the properties panel when the image is selected.
Constr.
Construction mode. While ON, the next shape drawn is saved with construction=true and renders dash-dot. Construction geometry is skipped by the extruder — it's a reference only (centerlines, axes, offset framing, bisectors). Toggle on an existing entity via the construction checkbox in the properties panel.
Points
Persistent snap-point markers on every entity. Glyph legend: filled dot = endpoint / spline knot / circle radius handle, hollow ring with pip = center / edge-midpoint / circle quadrant, square = rect / image corner, diamond = Bézier control handle. Off by default — toggle ON when placing a new shape so you can aim exactly at a reference on another shape without hovering to discover the snap point.
Axes
Toggles the two long coloured axis lines drawn through the origin. Axis colours + labels adapt to the current sketch plane: on XY horizontal is X→ / vertical is Y↑; on XZ vertical becomes Z↑; on YZ horizontal becomes Y→ and vertical Z↑. Labels sit at the ends of each axis. The origin marker (amber ring + "0") stays visible even when axes are hidden.
Rulers
Thin tick-marked strips along the top and left edges of the canvas with numeric labels at major grid steps and a coloured cursor-position triangle that tracks the mouse. Useful for quick measurement without relying on Auto Dim. Shares the grid's zoom-dependent step (1 mm / 0.1 mm / 0.01 mm).
Plane badge
Bottom-left chip showing the active sketch plane (PLANE XY / PLANE XZ / PLANE YZ / vector for a custom normal). Passive readout — no interaction.
Cursor readout
Bottom-right chip showing live SCAD world X / Y / Z of the mouse cursor (the existing sketch-local X / Y remains in the status bar). Each axis value is coloured per SCAD convention.
Fillet
Rounds the corner between two existing line entities that share a vertex. Click the tool → click the first line → click the second line (must share a vertex with the first). The shared corner is replaced with a tangent arc of the radius shown in the spinner next to the button (persisted per session). Source is rewritten atomically: the two lines are trimmed back to the tangent points, and a new arc(...) entity is inserted. Post-commit you can fine-tune by selecting the new arc and dragging its radius anchor. Esc cancels mid-selection. v1 limitation: only operates on line() entities; rect / bezier / spline / arc are not yet supported.
Chamfer
Straight bevel version of Fillet. Same two-click workflow, but instead of a tangent arc the shared corner becomes a straight line between two trim points whose distance from the vertex equals the "r" value in the spinner. Useful for 45° cuts and other linear corner treatments. Same v1 limitation: line entities only.
Smart guides
While drawing a new shape, dragging an anchor, or moving a selection, dashed yellow alignment lines appear when the cursor aligns with another entity:
Horizontal / vertical through any anchor — cursor snaps to that axis.
Line extension — cursor snaps along the infinite extension of any line segment.
Midpoint between two anchors — labeled ½, cursor snaps to the exact middle.
When two or more guides cross at the same point a bright × marker appears — this is a meaningful placement: e.g. horizontally aligned with object A, vertically aligned with object B, and along the extension of line C. Ideal for placing the third part of an arrangement.
Properties panel
When a single entity is selected, a panel in the bottom-right of the canvas shows every parameter as an editable input (point fields as X/Y pairs, scalars as single numbers). Images also get an opacity slider and +90° / +180° / −90° rotate buttons. All edits round-trip through the SCAD source.
Precision
Every coordinate and numeric value is rounded to 0.01 mm at mutation time. Grid snap tiers by zoom: 1 mm default → 0.1 mm when zoomed in → 0.01 mm when zoomed deeper. Drag, zoom-pan, click-to-edit, and serialization all pass through the same rounding, so there's no float-noise accumulation across operations.
Transforms
Function
Parameters
Description
translate
[x, y, z]
Move children by offset vector.
rotate
[x, y, z]
Rotate children (degrees).
scale
[sx, sy, sz]
Scale children. Scalar for uniform.
mirror
[x, y, z]
Mirror children over plane with given normal vector.
resize
[x, y, z], auto
Resize to target dimensions. auto fills unspecified dims proportionally.
Universal bolt-hole drill. type: "countersunk" / "counterbore" / "through". size: ISO metric string "M1".."M20" auto-sizes shank & head per DIN 7991 / DIN 912. Takes children to subtract from, or returns drill shape for difference().
Hole Patterns
Cut repeating patterns of holes through a shape. Two forms:
// 1) Generic wrapper — works on any shape
hole_pattern(pattern="hex", spacing=8, d=5, margin=4) { my_shape(); }
// 2) Shortcut arg on a primitive (cube / sphere / cylinder)
cube([80, 50, 4], cut_pattern="hex", spacing=8, hole_d=5, margin=4);
On primitives, prefix collision-prone args with hole_ — every arg that collides with a primitive's own args: hole_d, hole_r, hole_h, hole_center, hole_count, hole_radius, hole_through, hole_chamfer(_top/_bot), hole_fillet(_top/_bot), hole_thickness, hole_corner_r, hole_gap, hole_spokes. Non-conflicting args stay unprefixed: spacing, rows, cols, margin, angle, start_angle, anchor, clip, rib, equilateral, cut_shape. Inside hole_pattern(), drop all prefixes.
Pattern (layout)
Value
Description
"grid"
Rectangular rows × cols grid.
"hex"
Hex-packed staggered grid (odd rows shifted by spacing/2).
Ring-only: number of holes, ring radius, starting angle (degrees). Auto-sizes hole_d from arc length when rib is set.
angle
Linear-only: direction in degrees (0 = +X, 90 = +Y, 45 = diagonal). Default 0.
d / hole_d, r / hole_r
Cutter diameter / radius (d wins).
h / hole_h
Cutter height. 0 = auto from parent thickness + 0.2 overshoot.
through / hole_through
Overshoot for through-holes (default true).
thickness / hole_thickness
Arm width for plus/x; bowtie mid-width; diamond minor axis; radial spoke base chord.
spokes / hole_spokes
Number of spokes for radial/star shape (default 4; 2 = bowtie, 6 = hexagonal rosette).
corner_r / hole_corner_r
2D corner rounding for complex shapes (plus, x, bowtie, diamond).
gap / hole_gap
Space between the two triangles in diamond (0 = solid rhombus).
rib
Auto-fit mode: material width between cells. When set, evaluator computes spacing, hole_d, thickness, hole_gap, and margin. Cell size: grid/hex uses bbox/(rows×cols); linear uses projected length/count; ring uses arc length (2π·radius/count). For radial shapes, spoke sides become parallel so material between spokes is uniform.
equilateral
With rib on plus/x/bowtie/diamond: sets thickness = hole_d / sqrt(3). Ignored for radial (which uses the parallel-spoke formula instead).
anchor
Face to cut from: TOP (default), BOTTOM, LEFT, RIGHT, FRONT, BACK.
center / hole_center
[x, y] in-plane offset of the whole pattern.
clip
Drop cutters that straddle the parent silhouette (default true).
chamfer / hole_chamfer
Flat taper at both ends; widens opening by that amount.
chamfer_top, chamfer_bot
Per-end chamfer (or hole_chamfer_top, hole_chamfer_bot). Pass 0 to keep that end flat.
fillet / hole_fillet
Rounded transition at both ends (6-slice quarter-circle).
Involute spur gear. hub_d/hub_h add a boss cylinder above the gear. helix_angle (degrees) twists each tooth along the axis. optimized=true adds a ring of lightening holes between bore and teeth.
helical_gear
teeth, mod, pressure_angle, width, helix_angle, bore, backlash, center, $fn
Spur gear with helical twist.
herringbone_gear
teeth, mod, pressure_angle, width, helix_angle, bore, backlash, center, $fn
V-pattern double helical gear.
rack
teeth, mod, pressure_angle, width, height, backlash, center, $fn
Linear gear rack.
bevel_gear
teeth, mod, pressure_angle, width, cone_angle, bore, backlash, center, $fn
Bevel gear for angled shafts.
worm
starts, mod, pressure_angle, length, d, r, bore, center, $fn
Helical worm for worm-gear drives.
Structural Profiles
Thin-walled extrusions. All share: w (width), h (height), t (thickness), l (length), fillet, chamfer, center, $fn.
Function
Extra Parameters
Description
l_profile
fillet_outside, chamfer_outside
L-shaped cross-section.
u_profile
fillet_outside, chamfer_outside
U-shaped (channel).
o_profile
fillet_outside, chamfer_outside
Rectangular tube.
t_profile
tw
T-shaped. tw = web thickness.
i_profile
tw
I-beam. tw = web thickness.
Anchor Constants
Combinable with + for edges and corners (e.g. TOP + RIGHT + FRONT).
Constant
Value
Description
CENTER
[0, 0, 0]
Bounding box center
TOP
[0, 0, 1]
Z+ face
BOTTOM
[0, 0, -1]
Z- face
RIGHT
[1, 0, 0]
X+ face
LEFT
[-1, 0, 0]
X- face
BACK
[0, 1, 0]
Y+ face
FRONT
[0, -1, 0]
Y- face
Axis Constants
Constant
Value
Usage
X
[1, 0, 0]
X axis only
Y
[0, 1, 0]
Y axis only
Z
[0, 0, 1]
Z axis only
XY
[1, 1, 0]
X and Y axes
XZ
[1, 0, 1]
X and Z axes
YZ
[0, 1, 1]
Y and Z axes
Math Functions
Category
Functions
Trigonometry (degrees)
sin(x), cos(x), tan(x)
Rounding
abs(x), ceil(x), floor(x), round(x)
Exponents
sqrt(x), pow(x, y)
Logarithms
ln(x), log(x)
Comparison
min(a, b, ...), max(a, b, ...)
Constants
PI
View Navigation
Key
Action
Num 1
Front view
Ctrl + Num 1
Back view
Num 3
Right view
Ctrl + Num 3
Left view
Num 7
Top view
Ctrl + Num 7
Bottom view
Num 5
Toggle Ortho / Perspective
Transform
Key
Action
T
Translate mode
R
Rotate mode (Shift = 45° snap)
S
Scale mode
Selection & View
Key
Action
F
Fit view to selection
N
Fit view with normal
Esc
Deselect all
Delete
Delete selected object
Dimension Dragging
Key
Action
X
Constrain to X-axis
Y
Constrain to Y-axis
Z
Constrain to Z-axis
AI Assistant
The AI assistant helps you create, modify, and debug SCAD code through natural language conversation. It understands your current code and errors.
Setup
Open the hamburger menu and select AI Settings to configure a provider. Or click the dimmed AI button in the toolbar.
Provider
Notes
Claude (Anthropic)
Recommended. Best SCAD understanding.
OpenAI
GPT-4o and other OpenAI models.
DeepSeek
Cost-effective alternative.
Groq
Fast inference, open-source models.
OpenRouter
Access 100+ models with one key.
Ollama (Local)
Run locally, no API key needed.
Custom
Any OpenAI-compatible endpoint.
Usage
Feature
Description
Apply
Replace your entire code with the AI's suggestion.
Insert
Append the AI's code after your current code.
Images
Paste or upload reference images for the AI to see.
New Chat
Start a fresh conversation. Previous chat is saved to History.
History
Switch to the History tab to browse and reload past conversations.
Tips
Tip
Example
Be specific about dimensions
"Make a box 40mm wide, 20mm deep, 15mm tall"
Reference your code
"Add mounting holes to the enclosure"
Ask to fix errors
"Fix the error in my code" (errors are sent automatically)
Iterate on designs
"Make the walls thicker and add fillets"
Your API key is stored in your browser's localStorage and never sent to our servers. Code context is sent directly to your chosen AI provider.
Use SCAD+ from Claude and other AI apps
Install the SCAD+ MCP server and design with the AI app you already use — no API key: your Claude (or other) subscription does the thinking. The AI gets the SCAD+ language reference, checks every model with the real SCAD+ engine, and shows it in a live SCAD+ tab that updates as the conversation goes. Your own edits in that tab flow back to the AI.
Claude Desktop
Download the extension, open it, and click Install. Nothing else needed.
"Design a wall bracket for a 25 mm pipe with two M4 screw holes and show it in SCAD+"
"Make the walls 3 mm and round the edges" — the open SCAD+ tab updates in place
"I changed the height in SCAD+, continue from my version"
Continue a model later
Open the model in SCAD+ and choose Claude → Open in Claude Code (or Open in Claude Desktop). Claude starts with a prompt that connects this tab — press Enter, then say what to change. Claude gets the model and every update appears in this tab again. A tab whose Claude session has ended offers the same buttons.
Claude already running, or Cursor / VS Code? Use Copy prompt for Claude and paste it into the chat. Folder for Claude Code… sets where Claude Code starts.
Claude Code registers its claude-cli:// links after you use it interactively once. Your browser opens the Claude Code installed on the same system — add the SCAD+ MCP server there.
Notes
Requirements
Claude Code / Cursor / VS Code: Node.js 18 or newer. Claude Desktop brings its own.
Updates
Automatic — the server checks this site when it starts and fetches a newer version.
Offline
npx needs this site to start. To work offline, install once with npm i -g https://scadplus.code-box.pl/mcp/scadplus-mcp.tgz and register scadplus-mcp as the command (Claude Code: claude mcp add -s user scadplus -- scadplus-mcp).
Privacy
Everything runs on your computer. The live tab talks only to the local server (your browser may ask to allow access to devices on your local network — allow it).