I wanted to mount a small fan controller board to the inside of a server case, somewhere out of the airflow, screwed down so it couldn't rattle loose. Simple ask. I spent the better part of an hour trawling for a bracket that fit the board's odd mounting-hole spacing and the awkward bit of sheet metal I had to attach to, and found nothing. Plenty of things that were close. Nothing that was right. The holes were 38mm apart on one axis and 22mm on the other, and the world does not make a bracket for that.
So I stopped looking and opened OpenSCAD, and forty minutes later I had a part that fit exactly, on the first proper print. This post is about why that's now my default reflex, and the handful of things that make it work rather than waste an evening.
measure first, twice, with calipers
The whole approach lives or dies on measurement. I have a cheap pair of digital calipers and they are the most useful tool I own for this. Before I draw anything, I write down every dimension that matters: hole centres, hole diameters, the thickness of the thing I'm bolting to, the clearance around the board's components so the bracket doesn't foul a capacitor. I measure each one twice, because I will misread the calipers at least once, and a 0.5mm error on a hole spacing is the difference between "bolts straight in" and "bin it, start again".
The mistake I made early on was designing to the nominal dimension instead of the measured one. A board that says "2.5mm mounting holes" has 2.5mm holes the way a 2x4 is two inches by four. Measure the actual part in front of you.
why openscad, and not the fancy stuff
I know Fusion 360 exists and I know it's better at organic shapes and proper assemblies. For a bracket, I don't want any of that. A bracket is a box with some holes in it, and OpenSCAD lets me describe exactly that in a few lines of code I can read, version in git, and change by editing a number. It's CAD for people who'd rather type than push a mouse around, which on a Friday afternoon is me.
Here's roughly the shape of it. Parameterise everything, never hard-code a dimension twice:
hole_dx = 38; // measured hole spacing, long axis
hole_dy = 22; // measured hole spacing, short axis
hole_d = 3.2; // M3 clearance, measured screw was 2.9
wall = 3;
base_t = 2.5;
module bracket() {
difference() {
// base plate
cube([hole_dx + wall*2, hole_dy + wall*2, base_t]);
// four mounting holes
for (x = [wall + hole_d/2, hole_dx + wall + hole_d/2])
for (y = [wall + hole_d/2, hole_dy + wall + hole_d/2])
translate([x, y, -1])
cylinder(h = base_t + 2, d = hole_d, $fn = 24);
}
}
bracket();
The two things that took me a few prints to learn. First, holes need to be a touch bigger than the screw, not the same size, because the printer lays plastic slightly into the gap and a 3.0mm hole comes out as a 2.8mm hole you can't get an M3 through. I add 0.2mm and stopped having the problem. Second, set $fn low for holes and high for nothing else; a 24-sided cylinder prints fine and renders instantly, where $fn = 200 everywhere makes the preview crawl for no benefit you can see at this scale.
the print itself
This is the easy part by now. PLA, 0.2mm layers, three perimeters and 30% infill, which for a bracket is wildly overbuilt but I'd rather it be stiff than save ten minutes of plastic. The base plate goes flat on the bed so the mounting face is dead smooth and the holes print vertically, which keeps them round. Roughly forty minutes on my machine, and I went and made a coffee.
The first print was a fit check, not the final part. I printed it, offered it up to the board and the case, found the board holes were perfect and the case face needed the bracket 1.5mm taller so a connector cleared. Changed one variable, reprinted, done. The iteration loop is the real win here: a tweak costs a number and forty minutes, not a fresh order and a week of waiting for something that's still slightly wrong.
was it actually worth it
Honestly, on pure time, this one print probably broke even at best against buying a bracket, if a perfect bracket had existed, which it didn't. But that accounting misses the point. I now have an OpenSCAD file that makes this exact bracket forever, and a library of little modules (a standoff, a cable clip, a Pi mount) that I paste into the next thing. The marginal cost of the next custom part keeps falling, because half of it is already written.
The deeper shift is that "buy a part that nearly fits and bodge it" stopped being the obvious move. When the bracket I want doesn't exist, I no longer feel stuck. I measure, I type forty lines, I print, and an hour later I'm holding the thing that was in my head.
The one caveat I'd offer anyone starting down this road: respect the limits of the material. PLA is stiff but it creeps under sustained load and it goes soft if it lives somewhere warm, so a bracket holding a board inside a case is fine, and a bracket holding anything structural, or anything near a heat source, wants a different plastic or a different approach entirely. I learned that the boring way, with a printed clip that sagged over a fortnight on a sunny windowsill. For low-stress, fit-the-gap parts indoors, though, PLA is plenty, and that covers the vast majority of the brackets a homelab actually needs.
So that's the reflex now. For a board that needed holding still in a case, an afternoon in OpenSCAD gave me a part that fit on the first proper try and a file that'll make it again forever. That's a faintly ridiculous amount of satisfaction for a bracket, and I'll take it every time.