Cheatsheet: OpenSCAD

Find OpenSCAD syntax, copy a complete snippet, and open it in the browser playground to preview it in 3D. For the complete language, see the official OpenSCAD cheat sheet at openscad.org/cheatsheet.

Updated

How to use

Examples use core OpenSCAD syntax that works in the desktop app and in this playground. OpenSCAD is unitless; these snippets treat 1 unit as 1 mm.

Complete snippets
Every copy target is a complete model. Paste it into the playground or a .scad file and press Preview (F5) or Render (F6).
2D vs 3D
2D shapes (square, circle, polygon, text) must be extruded before exporting STL. Switch the playground to 2D to preview or export SVG/DXF directly.
Official reference
This page covers the most-used features. The official OpenSCAD cheat sheet (openscad.org/cheatsheet) and User Manual document every built-in module and function.
Open playground

Basics

Variables, comments, output, and resolution.

Variables and comments

// Variables are set once per scope (last assignment wins)
width = 40;   // mm
height = 10;
/* block comment */
cube([width, width / 2, height]);

Print values with echo()

size = [20, 10, 5];
echo("size =", size, "volume =", size.x * size.y * size.z);
cube(size);

Control curve smoothness

$fn = $preview ? 32 : 96; // fast preview, smooth render
cylinder(h = 10, d = 20);
translate([30, 0, 0]) sphere(d = 20, $fn = 12); // per-object override

Include or use a library (BOSL2)

// include <file> runs top-level code and imports modules, functions, and variables
// use <file> imports only modules and functions
include <BOSL2/std.scad>
cuboid([30, 20, 10], rounding = 2, $fn = 24);

3D primitives

cube()

cube([30, 20, 10]);                     // corner at origin
translate([40, 0, 0]) cube(10, center = true); // centered

cylinder() and cones

cylinder(h = 20, d = 10, $fn = 48);
translate([20, 0, 0]) cylinder(h = 20, d1 = 12, d2 = 0, $fn = 48); // cone
translate([40, 0, 0]) cylinder(h = 20, r = 6, center = true, $fn = 6); // hex prism

polyhedron()

polyhedron(
  points = [[0,0,0], [20,0,0], [20,20,0], [0,20,0], [10,10,15]],
  faces  = [[0,1,4], [1,2,4], [2,3,4], [3,0,4], [3,2,1,0]]
);

2D primitives

Preview in 2D mode, export SVG/DXF, or extrude into 3D.

square() and circle()

square([30, 20]);
translate([45, 10]) circle(d = 20, $fn = 64);

polygon()

polygon([[0, 0], [40, 0], [40, 10], [10, 30], [0, 30]]);

text()

text("OpenSCAD", size = 10, font = "Liberation Sans:style=Bold", halign = "center");

offset() for rounding and walls

offset(r = 3) square([30, 20]);                // grow with round corners
translate([45, 0]) difference() {                 // 2 mm outline
  square([30, 20]);
  offset(delta = -2) square([30, 20]);
}

Transformations

rotate()

rotate([0, 0, 45]) cube([30, 5, 5]);
translate([0, 20, 0]) rotate(a = 30, v = [1, 0, 0]) cube([30, 5, 5]);

scale() and resize()

scale([2, 1, 0.5]) sphere(d = 10, $fn = 48);
translate([30, 0, 0]) resize([20, 10, 5]) sphere(d = 10, $fn = 48);

mirror()

module part() translate([5, 0, 0]) cube([20, 10, 5]);
part();
mirror([1, 0, 0]) part();

color()

color("tomato") cube(10);
translate([15, 0, 0]) color([0.2, 0.5, 1, 0.6]) cube(10);

Transform order matters

translate([20, 0, 0]) rotate([0, 0, 45]) cube(10); // rotate, then move
rotate([0, 0, 45]) translate([20, 0, 0]) cube(10); // move, then orbit

Boolean operations

union()

union() {
  cube([30, 10, 10]);
  cylinder(h = 20, d = 10, $fn = 48);
}

difference(): cut holes

difference() {
  cube([40, 30, 5]);
  translate([20, 15, -1]) cylinder(h = 7, d = 8, $fn = 48); // taller than the plate
}

intersection()

intersection() {
  cube(20, center = true);
  sphere(d = 26, $fn = 64);
}

hull()

hull() {
  for (x = [0, 30], y = [0, 20]) translate([x, y, 0]) cylinder(h = 5, r = 4, $fn = 32);
}

minkowski()

minkowski() {
  cube([30, 20, 6]);
  sphere(r = 2, $fn = 24);
}

Extrusion

linear_extrude()

linear_extrude(height = 10) offset(r = 2) square([30, 20]);
translate([45, 10, 0]) linear_extrude(height = 20, twist = 90, scale = 0.5, slices = 40)
  square(10, center = true);

rotate_extrude()

rotate_extrude($fn = 96)
  translate([15, 0]) circle(r = 4, $fn = 32); // torus

Embossed text

cube([60, 20, 3]);
translate([30, 10, 3]) linear_extrude(1)
  text("HELLO", size = 8, halign = "center", valign = "center");

Modules and functions

Define a module

module rounded_plate(size = [40, 30], r = 4, h = 3) {
  hull() for (x = [r, size.x - r], y = [r, size.y - r])
    translate([x, y, 0]) cylinder(h = h, r = r, $fn = 32);
}
rounded_plate();
translate([0, 40, 0]) rounded_plate([60, 20], r = 8);

Pass geometry with children()

module on_corners(size) {
  for (x = [0, size.x], y = [0, size.y]) translate([x, y, 0]) children();
}
on_corners([40, 30]) cylinder(h = 5, d = 6, $fn = 32);

Define a function

function inch(x) = x * 25.4;
function clamp(v, lo, hi) = min(max(v, lo), hi);
cube([inch(1), inch(0.5), clamp(12, 2, 8)]);

Recursive function

function sum(v, i = 0) = i >= len(v) ? 0 : v[i] + sum(v, i + 1);
heights = [2, 5, 3, 8];
echo(total = sum(heights));
for (i = [0 : len(heights) - 1]) translate([i * 12, 0, 0]) cube([10, 10, heights[i]]);

Loops, conditions, and lists

for loop over a range

for (i = [0 : 4]) translate([i * 15, 0, 0]) cube([10, 10, 5 + i * 3]);

Nested loop grid

for (x = [0 : 10 : 40], y = [0 : 10 : 20])
  translate([x, y, 0]) cylinder(h = 3, d = 6, $fn = 24);

Polar pattern

count = 8;
for (i = [0 : count - 1]) rotate([0, 0, i * 360 / count])
  translate([20, 0, 0]) cylinder(h = 5, d = 6, $fn = 24);

if / else

rounded = true;
if (rounded) cylinder(h = 10, d = 20, $fn = 64);
else cube([20, 20, 10], center = false);

List comprehension and let()

points = [for (i = [0 : 5]) let(a = i * 60) [20 * cos(a), 20 * sin(a)]];
polygon(points);

intersection_for()

intersection_for(a = [0, 60, 120])
  rotate([0, 0, a]) cube([40, 20, 10], center = true);

Debugging modifiers

# highlight and % ghost

difference() {
  cube([30, 30, 10]);
  #translate([15, 15, -1]) cylinder(h = 12, d = 10, $fn = 32); // show the cutter
}
%translate([40, 0, 0]) cube(10); // reference only, not exported

! root and * disable

cube(10);
*translate([15, 0, 0]) sphere(5); // disabled
translate([30, 0, 0]) cylinder(h = 10, d = 8); // prefix with ! to render only this

assert()

wall = 2;
assert(wall >= 1.2, "Walls thinner than 1.2 mm may not print");
cube([20, 20, wall]);

Customizer parameters

Top-level variables with special comments become form controls.

Sliders, dropdowns, and checkboxes

/* [Size] */
width = 40;      // [10:1:100]
height = 10;     // [2:0.5:30]
/* [Style] */
shape = "round"; // [round, square]
hollow = false;
/* [Hidden] */
$fn = 64;

difference() {
  if (shape == "round") cylinder(h = height, d = width); else cube([width, width, height]);
  if (hollow) translate([0, 0, 2]) cylinder(h = height, d = width - 4);
}

Import and export

import() files

// 2D: SVG or DXF; 3D: STL, OFF, 3MF
linear_extrude(3) import("logo.svg", center = true);
// import("part.stl");

projection(): 3D to 2D

projection(cut = false) rotate([30, 0, 0]) cylinder(h = 20, d = 20, $fn = 6);

FAQ