How to Use OpenSCAD for Parametric Maker Projects: Code-Based 3D Design
Introduction
OpenSCAD is a code-based 3D CAD program. Instead of clicking and dragging, you write scripts that define geometry using code — cubes, spheres, cylinders, and transformations. This approach is fundamentally different from traditional CAD. Parameters are variables that you change at the top of the file, and the entire model regenerates. This makes OpenSCAD the best tool for maker projects that need parametric designs: customizable phone cases, dimensioned enclosures, gear generators, living hinges, parametric box creators, and any project where dimensions need to change frequently. This guide covers the OpenSCAD language, the essential primitives and transformations, modules and functions, and the parametric workflows that make OpenSCAD unique among maker design tools.
What You Need
- OpenSCAD (download from openscad.org)
- Basic programming knowledge (variables, functions, conditionals)
- A text editor (OpenSCAD has a built-in editor, or use VS Code with the OpenSCAD extension)
Step 1: The OpenSCAD Language Basics
Every OpenSCAD script is a text file with .scad extension. You write code, press F5 to preview, F6 to render, and File > Export to save STL.
Basic primitives:
// Cube cube([width, depth, height]); cube([20, 30, 10]); // 20x30x10 mm box // Sphere sphere(r=radius); sphere(r=15); // Cylinder cylinder(h=height, r=radius); cylinder(h=20, r=10); // Height 20, radius 10 // Cylinder with different top/bottom (cone) cylinder(h=20, r1=10, r2=5); // Bottom radius 10, top radius 5 // 2D primitives (must be extruded to 3D) square([width, height]); circle(r=radius);Transformations:
// Translate (move) translate([x, y, z]) cube([10, 10, 10]); // Rotate rotate([x_angle, y_angle, z_angle]) cube([10, 10, 10]); // Scale scale([x_factor, y_factor, z_factor]) sphere(r=10); // Mirror mirror([axis_x, axis_y, axis_z]) cube([10, 10, 10]); // Resize resize([new_x, new_y, new_z], auto=true) sphere(r=10);Boolean operations:
// Union - combine multiple objects union() { cube([20, 20, 10]); translate([10, 10, 10]) cylinder(h=15, r=5); } // Difference - subtract one object from another difference() { cube([30, 30, 10]); // Base translate([15, 15, -1]) cylinder(h=12, r=8); // Hole through base } // Intersection - keep only overlapping regions intersection() { cube([20, 20, 20]); sphere(r=15); }Variables and parameters:
// Define parameters at the top of the file width = 50; depth = 30; height = 20; wall_thickness = 2; hole_diameter = 5; difference() { cube([width, depth, height]); translate([wall_thickness, wall_thickness, wall_thickness]) cube([width - wall_thickness*2, depth - wall_thickness*2, height]); translate([width/2, depth/2, -1]) cylinder(h=height+2, d=hole_diameter); }Conditional logic:
make_lid = true; if (make_lid) { translate([0, depth + 5, 0]) cube([width, depth, wall_thickness]); }Step 2: Extruding 2D to 3D
OpenSCAD uses 2D primitives with extrusion to create complex 3D shapes:
// Linear extrude - pull a 2D shape upward linear_extrude(height=10) circle(r=10); // Linear extrude with twist linear_extrude(height=30, twist=90) square([10, 10], center=true); // Linear extrude with scale (tapered extrusion) linear_extrude(height=20, scale=0.5) circle(r=10); // Rotate extrude - spin a 2D profile around the Z axis rotate_extrude() translate([10, 0, 0]) circle(r=3); // This creates a torus (donut shape)Creating profiles for laser-cut parts:
// A bracket profile, extruded to material thickness material_thickness = 3; bracket_width = 40; bracket_height = 30; hole_d = 5; linear_extrude(height=material_thickness) difference() { square([bracket_width, bracket_height]); translate([bracket_width/2, bracket_height/2]) circle(d=hole_d); }Step 3: Modules (Reusable Functions)
Modules let you define reusable components:
// Define a mounting hole module module mounting_hole(diameter, depth) { cylinder(h=depth, d=diameter); } // Define a box module module box(w, d, h, wall) { difference() { cube([w, d, h]); translate([wall, wall, wall]) cube([w - wall*2, d - wall*2, h]); } } // Use the modules box(width=50, depth=30, height=20, wall=2); translate([10, 10, -1]) mounting_hole(diameter=4, depth=25); translate([40, 10, -1]) mounting_hole(diameter=4, depth=25);Parameterized box with lid:
// Parameters box_w = 60; box_d = 40; box_h = 30; wall = 2; lid_tolerance = 0.2; screw_d = 3; // Main box module main_box() { difference() { cube([box_w, box_d, box_h]); translate([wall, wall, wall]) cube([box_w - wall*2, box_d - wall*2, box_h - wall + 0.01]); // Screw holes for (x = [wall*2, box_w - wall*2]) { for (y = [wall*2, box_d - wall*2]) { translate([x, y, -1]) cylinder(h=wall+2, d=screw_d); } } } } // Lid module lid() { translate([0, box_d + 5, 0]) difference() { cube([box_w, box_d, wall + 2]); // Recessed lip translate([wall + lid_tolerance, wall + lid_tolerance, wall]) cube([box_w - wall*2 - lid_tolerance*2, box_d - wall*2 - lid_tolerance*2, wall + 0.01]); } } main_box(); lid();Step 4: Loops and Arrays
For loops:
// Grid of holes for (x = [0:10:50], y = [0:10:30]) { translate([x, y, -1]) cylinder(h=5, d=3); }Arrays of positions:
hole_positions = [ [10, 10], [40, 10], [10, 25], [40, 25] ]; for (pos = hole_positions) { translate([pos[0], pos[1], -1]) cylinder(h=5, d=3); }Step 5: Living Hinges for Laser Cutting
OpenSCAD excels at generating laser-cut designs with living hinges:
// Parameters width = 80; height = 60; material = 3; // 3mm plywood hinge_length = 40; hinge_y = 30; cut_width = 0.2; // Kerf compensation // Base plate with hinge cuts difference() { square([width, height]); // Living hinge cuts (parallel slits) for (i = [0:2:hinge_length]) { translate([width/2 - hinge_length/2 + i, hinge_y - cut_width/2]) square([cut_width, 10]); } // Mounting holes translate([10, 10]) circle(d=3); translate([width-10, 10]) circle(d=3); translate([10, height-10]) circle(d=3); translate([width-10, height-10]) circle(d=3); }Exporting for laser cutting:
- Design in 2D (use only square, circle, and 2D Boolean operations)
- Do NOT extrude — keep it 2D
- File > Export > Export as DXF
- Import the DXF into LightBurn or LaserGRBL
Step 6: Gear Generator
Use the MCAD library (built into OpenSCAD) for gears:
include <MCAD/gears.scad> // Parameters teeth = 20; pitch = 1; // Module (metric) thickness = 5; bore = 5; spur_gear( modul=pitch, tooth_number=teeth, width=thickness, bore=bore, pressure_angle=20, helix_angle=0, optimized=true );Or build a custom gear with involute profiles for more control.
Step 7: Customizer Integration
OpenSCAD files can be made into web-based customizers on Thingiverse and Printables:
// Thingiverse Customizer parameters /* [Dimensions] */ width = 50; // [20:200] depth = 30; // [20:150] height = 20; // [5:100] wall = 2; // [1:5] /* [Features] */ lid = true; // [true,false] vent_holes = 5; // [0:20] /* [Hidden] */ $fn = 50; // Facets for circlesVariables with comment annotations become sliders and checkboxes in the web customizer.
Tips for OpenSCAD Success
- Use $fn for circle quality. $fn = 50 for preview, $fn = 100 for final render. Higher = smoother but slower.
- Always preview before rendering. F5 (preview) is instant. F6 (render) takes time but produces clean geometry.
- Use Render before STL export. Exporting from preview can produce non-manifold meshes.
- Compartmentalize with modules. Each module should do one thing. Build complex models from simple modules.
- Use hull() for connecting shapes. hull() creates the convex hull of multiple objects — perfect for brackets and connectors.
- Use minkowski() for rounded corners. minkowski() { cube([10,10,10]); sphere(r=2); } creates a cube with rounded edges.
- Comment generously. OpenSCAD files are source code. Comments explain intent.
- Use linear_extrude for laser parts. Keep designs 2D, export as DXF. One OpenSCAD file can generate both 3D printed and laser-cut parts.
Conclusion
OpenSCAD is the ultimate parametric design tool for makers. Code-based design means full version control, infinite customization, and the ability to generate families of parts from one source file. The combination of primitives, transformations, Boolean operations, and modules handles every maker project from simple brackets to complex gearboxes. Export 2D profiles for laser cutting, 3D solids for printing, or parameterized models for the Thingiverse Customizer. Once you think in code instead of clicks, you will design faster, iterate more confidently, and never redraw a dimension line again.
Related Guides
- How to Use FreeCAD for Makers: Parametric CAD for 3D Printing, Laser Cutting, and CNC
- How to Design Snap-Fit Joints and Living Hinges for 3D Printed Parts
- How to Install Threaded Inserts in 3D Printed Parts for Strong, Reusable Hardware
- Designing Enclosures for Electronics Projects: Materials, IP Ratings, Ventilation, and Cable Entry
- Build a Cyberdeck: Custom Portable Computer with a Laser-Cut and 3D Printed Enclosure
- Gridfinity Modular Storage System: Baseplates, Bins, and Custom Parametric Inserts
- How to Design and 3D Print Functional Threads: Screws, Nuts, and Threaded Inserts
- How to Create Laser-Cut Living Hinges in Wood and Acrylic