Parametric Design with OpenSCAD: Generate Custom Bolts, Nuts, and Hardware
Most parametric CAD tools make you drag handles and click through dialog boxes to change a dimension. OpenSCAD flips that around: you write code, and the model is the output of that code. Change one variable — bolt diameter, hole spacing, wall thickness — and the entire model regenerates instantly. For anything you need in a family of sizes (mounting brackets, spacers, hardware, enclosures with configurable dimensions), that's a fundamentally faster workflow than redrawing geometry by hand each time.
Why OpenSCAD Instead of a GUI-Based CAD Tool
Fusion 360, FreeCAD, and similar tools are genuinely better for organic shapes, complex assemblies, and anything where you're visually sculpting a form. OpenSCAD is better specifically when the thing you're designing is really a formula with a few inputs — a bolt is diameter, length, and head shape; a project box is width, height, depth, and wall thickness. Once you've written that formula once, generating a new size is changing a number, not redrawing a shape. The tradeoff is a steeper initial learning curve, since you're writing code instead of clicking, and no native fillets/chamfers as easy as GUI tools make them (`minkowski()` can approximate rounded edges, but it's slow to render on complex geometry).
The Core Mental Model
OpenSCAD models are built from a small set of primitive solids — cube(), cylinder(), sphere() — combined using boolean operations: union() to merge shapes, difference() to subtract one from another (this is how you cut holes), and intersection() to keep only the overlap between shapes. Everything else is variables, loops, and modules (OpenSCAD's version of functions) built on top of those primitives.
A Parametric Hex Bolt and Matching Nut
Here's a working example that generates a hex-head bolt and a matching hex nut, both driven by the same diameter and thread-pitch variables so they stay consistent with each other:
// ---- Parameters ---- bolt_diameter = 6; // shaft diameter, mm (M6-ish) bolt_length = 25; // shaft length, mm head_height = 4; head_width = bolt_diameter * 1.8; // flat-to-flat hex width nut_height = 5; // ---- Hex bolt ---- module hex_bolt() { union() { // Hex head — cylinder() with $fn=6 draws a hexagonal prism cylinder(h=head_height, d=head_width, $fn=6); // Shaft translate([0, 0, head_height]) cylinder(h=bolt_length, d=bolt_diameter, $fn=32); } } // ---- Hex nut (head shape with a hole through it) ---- module hex_nut() { difference() { cylinder(h=nut_height, d=head_width, $fn=6); // Slightly oversized hole for print tolerance translate([0, 0, -1]) cylinder(h=nut_height+2, d=bolt_diameter+0.3, $fn=32); } } hex_bolt(); translate([head_width*1.5, 0, 0]) hex_nut();The trick worth noticing: cylinder() with a low $fn value doesn't draw a circle, it draws a polygon — $fn=6 gives you a perfect hexagon for free, instead of manually plotting six points. This is the single most useful shortcut for hardware-style parts in OpenSCAD.
On Actual Threads
Notice the shaft above is a plain smooth cylinder, not threaded. That's deliberate — real ISO/UTS thread geometry (helical grooves at the correct pitch and profile angle) isn't something worth hand-rolling from scratch, and a naive thread approximation can produce a bolt that looks right in the preview but doesn't actually thread into a real nut. For working printable threads, use an established library instead: threads.scad is a solid, focused option, and the more comprehensive BOSL2 library includes correct thread modules alongside a large set of other mechanical primitives. Both are drop-in include files — this smooth-shaft version above is meant as a heat-set-insert-friendly bolt substitute (works well combined with a printed heat-set insert and a real machine screw) rather than a fully self-threaded fastener.
Making It Actually Parametric
The example above is already parametric in the sense that matters — every dimension is a named variable at the top, not a magic number buried in the geometry. To make a whole family of bolt sizes, wrap the parameters and the two modules in a single generator module that takes size as an argument, and call it once per size you need. That's the same pattern used in the OpenSCAD bolt/nut generator paste linked below — take a look at the real, tagged version for a more complete implementation with a size table built in.
Related Guides
- How to Use OpenSCAD for Parametric Maker Projects: Code-Based 3D Design
- How to Install Threaded Inserts in 3D Printed Parts for Strong, Reusable Hardware
- Gridfinity Modular Storage System: Baseplates, Bins, and Custom Parametric Inserts
- How to Use FreeCAD for Makers: Parametric CAD for 3D Printing, Laser Cutting, and CNC
- 3D Printing: Fixing Under-Extrusion
- 3D Printer File Formats Explained: STL vs 3MF vs OBJ vs STEP, and Which to Use When
- 3D Print Nozzle Sizes Reference
- How to Design and 3D Print Functional Threads: Screws, Nuts, and Threaded Inserts