Cookbook · browseable

Example gallery

A cookbook of real prompts and the parametric OpenSCAD they produced. Copy any prompt into the AI CAD Modeler and you'll get back a render you can iterate on, or paste the code directly to start tweaking.

BOSL2 and MCAD ship with the in-browser editor.

Snippets using use <BOSL2/std.scad>, use <BOSL2/gears.scad>, use <MCAD/involute_gears.scad>, etc. work without any extra setup — the libraries are lazy-fetched and mounted into the WASM filesystem the first time a snippet references them, then cached for the rest of your session. Other libraries (NopSCADlib, Round-Anything, …) aren't bundled yet — inline the helpers or use desktop OpenSCAD.

1 · M3 corner bracket

The "hello world" of parametric CAD. Two perpendicular plates with mounting holes on each.

Prompt

M3 corner bracket, 30 mm legs, 20 mm wide,
4 mm thick. Two M3 clearance holes per leg,
5 mm in from each end.

Generated code

leg_length = 30;
leg_width  = 20;
thickness  = 4;
hole_d     = 3.2;
inset      = 5;
$fn = 48;

// @feature: corner_holes
module corner_holes() {
  for (x = [inset, leg_length - inset])
    translate([x, leg_width/2, -1])
      cylinder(h=thickness+2, d=hole_d);
}

// @feature: leg
module leg() {
  difference() {
    cube([leg_length, leg_width, thickness]);
    corner_holes();
  }
}

leg();
rotate([0, -90, 0])
  translate([0, 0, -thickness]) leg();

2 · Project enclosure with removable lid

A box with internal standoffs for a PCB, M3 brass-insert bosses, and a sliding lid.

Prompt

Project box 100 × 60 × 35 mm OD, 2 mm wall,
2 mm fillets. Four M3 brass-insert standoffs on
a 92 × 52 mm pattern. 1 mm internal lid lip.
USB-C cutout (9×4 mm + 0.5 mm clearance) on
the short side.

Generated code (excerpt)

box      = [100, 60, 35];
wall     = 2;
corner_r = 2;
pad_xy   = [92, 52];
$fn = 48;

// @feature: shell
module shell() {
  difference() {
    linear_extrude(box[2])
      offset(r=corner_r) offset(r=-corner_r)
        square([box[0], box[1]], center=true);
    translate([0, 0, wall])
      linear_extrude(box[2])
        offset(r=-wall) square([box[0], box[1]], center=true);
  }
}

// @feature: standoffs
module standoffs() {
  for (sx = [-pad_xy[0]/2, pad_xy[0]/2],
       sy = [-pad_xy[1]/2, pad_xy[1]/2])
    translate([sx, sy, wall])
      difference() {
        cylinder(h=7, d=6);
        cylinder(h=5, d=4);  // insert bore
      }
}

difference() {
  union() { shell(); standoffs(); }
  translate([box[0]/2-2, 0, 10])
    cube([5, 9.5, 4.5], center=true);   // USB-C
}

3 · Involute spur gear (BOSL2)

Real involute teeth, parametric tooth count + module, bore + keyway, chamfered faces. Powered by BOSL2 — mounted into the editor automatically on first use.

Prompt

Involute spur gear, 24 teeth, module 2,
8 mm bore, 3 × 2 mm keyway, 6 mm thick.
Use BOSL2.

Generated code

include <BOSL2/std.scad>
include <BOSL2/gears.scad>

teeth    = 24;
mod      = 2;
bore     = 8;
keyw     = 3;
keyd     = 2;
thick    = 6;

// @feature: gear
difference() {
  spur_gear(teeth=teeth, mod=mod, thickness=thick,
            shaft_diam=bore);
  // @feature: keyway
  translate([bore/2-keyd, -keyw/2, -1])
    cube([keyd+0.5, keyw, thick+2]);
}
First BOSL2 paste of the session triggers a ~1 MB download.

The full BOSL2 source (56 .scad files, ≈ 4 MB raw / ≈ 1 MB gzipped) is fetched the first time the editor sees use <BOSL2/…> or include <BOSL2/…>. Subsequent renders re-use the cached bundle for the rest of the session, so iteration on the gear is instant.


4 · Twisted hexagonal vase

Vase-mode-printable single wall, hexagonal profile twisted around Z.

Prompt

Hexagonal twisted vase, 60 mm tall,
30 mm OD base, 24 mm OD top, 180° twist.
Single wall — print in vase mode.

Generated code

h     = 60;
r1    = 15;
r2    = 12;
twist = 180;

// @feature: vase_outer
linear_extrude(height=h, twist=twist,
               slices=120, scale=r2/r1)
  circle(r=r1, $fn=6);

5 · Gridfinity-style storage bin

2×1 footprint, 3U tall, single cavity, magnet holes on the base. Compatible with the Gridfinity ecosystem.

Prompt

Gridfinity bin, 2×1 footprint, 3U tall,
single internal cavity, four 6×2 mm magnet
holes in the base, label tab on the long side.

Generated code

u          = 42;       // Gridfinity unit (mm)
cells_x    = 2;
cells_y    = 1;
height_u   = 3;        // 1U = 7 mm
wall       = 1.2;
mag_d      = 6;
mag_depth  = 2.4;
corner_r   = 4;
$fn = 48;

outer_w = cells_x * u;
outer_d = cells_y * u;
bin_h   = height_u * 7;

// 2D rounded rectangle, lower-left corner at the origin
module rrect(w, d, r) {
  hull() {
    translate([r,     r])     circle(r);
    translate([w-r, r])     circle(r);
    translate([r,     d-r]) circle(r);
    translate([w-r, d-r]) circle(r);
  }
}

// @feature: bin_body — outer shell with hollow cavity
module bin_body() {
  difference() {
    linear_extrude(bin_h) rrect(outer_w, outer_d, corner_r);
    translate([wall, wall, 2])
      linear_extrude(bin_h)
        rrect(outer_w-2*wall, outer_d-2*wall, corner_r-wall);
  }
}

// @feature: magnet_holes — four Ø6×2.4 mm pockets per cell
module magnet_holes() {
  for (cx = [0:cells_x-1], cy = [0:cells_y-1],
       ox = [8, u-8], oy = [8, u-8])
    translate([cx*u+ox, cy*u+oy, -0.1])
      cylinder(h=mag_depth+0.2, d=mag_d);
}

// Assemble: bin body minus magnet pockets
difference() {
  bin_body();
  magnet_holes();
}
This is a simplified Gridfinity profile.

The real Gridfinity standard has a precise tapered base profile that mates with baseplates. This example renders a hollow bin with the right footprint and magnet pattern — perfect for a first iteration. Ask the agent: "Add the standard Gridfinity base profile (0.8 mm + 1.8 mm + 2.15 mm tapered chamfers)" to extend it.


6 · Cable clip (snap-fit, no screws)

Prompt

Wall-mount cable clip for a Ø6 mm cable,
3M VHB tape backing 25×10 mm. Snap-fit
opening with 0.5 mm interference, 1.5 mm lip.

Generated code

cable_d     = 6;
opening     = cable_d - 0.5;   // snap interference
backing     = [25, 10, 2];
wall        = 2;
$fn = 48;

// @feature: clip_ring
module clip_ring() {
  difference() {
    circle(d=cable_d+2*wall);
    circle(d=cable_d);
    translate([-opening/2, 0]) square([opening, cable_d]);
  }
}

linear_extrude(backing[2])
  offset(r=1.5) offset(r=-1.5)
    square([backing[0], backing[1]], center=true);
translate([0, 0, backing[2]])
  linear_extrude(8) clip_ring();

7 · Photo frame for a lithophane

Prompt

Picture frame for a 100×100 mm lithophane.
3 mm border, 1 mm bezel lip to hold the
litho, M3 keyhole hanger on the back.

Generated code (key feature)

litho = [100, 100];
border = 3;
bezel  = 1;
thick  = 4;
$fn = 48;

difference() {
  cube([litho[0]+2*border, litho[1]+2*border, thick]);
  translate([border, border, bezel])
    cube([litho[0], litho[1], thick]);

  // @feature: keyhole_hanger
  translate([litho[0]/2+border, litho[1]+border-8, thick-1])
    union() {
      cylinder(h=2, d=7);
      translate([-1.5, -10, 0])
        cube([3, 10, 2]);
    }
}

8 · Knurled thumb knob

Prompt

Thumb knob, Ø25 mm × 12 mm tall, M5
threaded brass-insert bore (4.0 mm bore,
6 mm deep). 24 vertical knurls on the
outside. 1 mm chamfer top edge.

Generated code

d        = 25;
h        = 12;
insert_d = 4;
insert_h = 6;
n_teeth  = 24;
tooth_d  = 1.2;
$fn = 96;

// @feature: knob_body
difference() {
  union() {
    cylinder(h=h-1, d=d);
    translate([0,0,h-1])
      cylinder(h=1, d1=d, d2=d-2);
  }
  // @feature: knurls
  for (i = [0:n_teeth-1])
    rotate([0,0, i*360/n_teeth])
      translate([d/2, 0, -1])
        cylinder(h=h+2, d=tooth_d, $fn=12);
  // @feature: insert_bore
  translate([0,0,-0.1])
    cylinder(h=insert_h+0.2, d=insert_d);
}

More to come

This cookbook grows as we ship. Want a recipe added? Ask us, or just generate the part with the agent and share the prompt with the community.

Copy any prompt above into the agent

You'll get a parametric model back in seconds — render, tweak, export. Save your version to your history; share the prompt with the world.

Open the agent