OpenSCAD ISO metric thread library / functions (updated)

by TrevM Apr 25, 2014
Download All Files

Please Login to Comment

M2 end up with space between centre and pitch. anyone can help me?

Thanks for this library. I was having trouble slicing the threads generated by functions using th_in_pt()/th_out_pt() in Cura 3.6.0 (there was a problem with the thread segment 'overlap' not overlapping) so I've uploaded a fixed version.

Cura users: Use the github version or the one by JustKrys

Google will NEVER be my friend >:O

It can be, but it brought me here first. I didn't notice there was a Cura slicing problem at first and then it was a simple fix anyway. I've binned mine, the world doesn't need more unmaintained code.

If you want to be totally sure then write it yourself

Is it easy way to build fine thread pitch? I need fine thread M25/ Could you help me?

$fn=100; // purely to make it smooth at that diameter

// 25 = 25 mm diameter
// 16 = 16 mm length (height)
// 1.0 = thread pitch of 1 mm

Has anyone made an M36? I have no idea how to generate these but maybe someone has already done one and could send over?

Thanks in advance!

im trying to create an M8 thread but printing in PLA is very tight and resin on DLP even tighter on metal M8 nuts, i see you allow a nut tolerance but not thread or bolt. any suggestions to why they are so tight?

UPDATE: i was using the original scad but i will try with the new one.

I'm afraid a varies a lot dependent upon your slicer and your printer.
It works as-is with no changes on my set-up.
But YOU have full control.

hex_bolt(8,16); // make an M8 x 16 ISO bolt
hex_nut(8); // make an M8 ISO nut

Instead, try:


These will all give over sized by 0.3 mm.
It's a library, ultimately you are in full control :-)

Hi Trev,

Thanks for the great work.

I uncommented to make a M6 Nut then got this, can you help me out?


Bit mystified.
I'm using latest OpenSCAD Version 2015.03-2 (latest) on MS Windows 7.
It's been working for 3 years!
Do other things work for you in OpenSCAD?

I tried a different computer and it worked. I guess my computer just went nuts when I tried to create a nut. lol. Thanks a lot tho.

can you please put all the values needed to be changed into the top part of the program so that a person doesn't have to quick read to find the values to change in the program it is very annoying to have to find where each neads to be changed

and make a library to look up and change the values automaticly by placing

the value of the nut or bolt size would be set for "M8x20"

so the program would reconise that i want a m8 bolt set to 20mm length
and automatically calculate the dims for the matching nut

bolt head size would=13
thread size would = 8
thread length would = 20

i am a programer but openscad just confuses me
i have tried to modify your program and just do not know enough about openscad to make it work

right now i am trying to just make a M8x50 bolt and matching nut and am jut getting realy pissed off that i have to keep fudgeing and printing to make them fit i had them realy close then closed the program before i saved it and now i have to start over because i don't remember if it was 1mm or .5mm or.75mm that made them fit

i hope you understand what i am trying to say

Hi Jeffrey,
Very shocked, very surprised, very humbled, very thankful.
I've actually never received a tip before in my life!
BR, Trev

I'm a big fan of public domain and was looking for a thread library. Tag, you're it :)

I use unlicense.org for my own stuff. Fancy public domain dedication.

Thanks again!

Comments deleted.

Trev, in openscad the threads on the bolts are not attached to the centre. I'm using the examples provided in your source and none of them seem to be attached. Should this be ignored?

Yes, I noticed that recently, I think it's something to do with new version OpenSCAD, but not investigated yet.
No, do NOT ignore, it gives bad prints.

Trev -

I think you might have meant something different with "thread_in_ring" than what this library does. I changed it to this:

module thread_in_ring(dia,hi,thk)
cylinder(r = (thk/2),h = hi); // thk specifies the OD of the sleeve.
translate([0,0,-1]) cylinder(r = (dia/2)+0.1, h = hi+2); // don't add it to the height of the inner cylinder.

See further down:
comment by Pr1mus285 Jun 18th, 2015
comment by ketil 26th May 2014 and my reply on 27th May 2014
Yes, you are absolutely correct :-)


Thanks for this library. I've started extending it to do socket-head cap screws and I'll upload it soon.

Thanks for the work on this! I'm struggling to work out how to "tap" threads into objects though. I'd have expected to be able to difference() the thread out of the object, but that just cuts the thread and leaves the middle section solid. I've tried using a cylinder but it cuts most of the thread away too. Am I missing a way to do this?

Thanks again

I think I've worked out a way to do this:

difference() {
// The object to cut a thread into
cube([10, 10, 10]);
difference() {
cylinder(r=thread_diameter/2, h=thread_length);
thread_in(thread_diameter, thread_length);

Or with indentation: https://paste.ee/p/WD3Bb

very cool, thank you. unlike all other libs I have seen, extremely small and easy to use.

one thing would be nice to add - add more bolt head types (for cross screwdriver, for example) or add call to draw bolt without head. Still this is easy to implement by taking rolson_hex_bolt module code as a base anyway.

You have lots of ideas, license is 'public domain'.
Go for it, do a remix.
The whole idea is that this is a library to help users with their own designs.
I will be more than happy for you to copy and expand, start your own designs :-)

And another one screw without head with sharp end (mounting screw?) like this one http://www.master-krepezh.ru/vinty_44.html

module mounting_screw(dia, hi) {
// inner thread radius,
// taken from modules ISOThread: thread_out_centre, thread_out_centre_pitch
p = get_coarse_pitch(dia);
h = (cos(30)p)/8;
Rmin = (dia/2) - (5
h); // as wiki Dmin

// bottom radius == inner thread radius
hr = Rmin;    
// bottom height
hhi = hr/2;

// the whole screw height includes both sharp end height, thread height and bottom height,
// so let's shorten thread a bit
thread_height = hi;// - hr - hhi;

difference() {
  union() {
    // sharp end (height is equal to its bottom radius)
    translate([0, 0, hhi+thread_height+0.1]) cylinder(r1=hr, r2=0, h=hr, $fn=100);

    // bottom: cutted cylinder with notch
    cylinder(r1=hhi, r2=hr, h=hhi, $fn=100);

    // thread
    translate([0,0,hhi])    thread_out(dia,thread_height+0.1);
    translate([0,0,hhi])    thread_out_centre(dia,thread_height+0.1);

  // use head radius hr for relative notch proportions
  translate([0, 0, (hhi*5/3)/2-0.1]) cube([hr/4, dia+0.2, hhi*5/3], center=true);


I have added 2 more options to render:


  • Screw with rounded crosshead.
  • @param dia thread diameter (3=M3, 4=M4 etc)
  • @param hi threaded rod height
    module crosshead_screw(dia, hi) {
    // head height and radius
    hhi = rolson_hex_bolt_hi(dia);
    hr = rolson_hex_bolt_dia(dia)/2;
    round_radius = hhi/3;

    // rounded head
    difference() {
    union() {
    translate([0, 0, round_radius])cylinder(r = hr,h = hhi-round_radius, $fn=100);
    translate([0, 0, round_radius]) rotate_extrude($fn=100)
    translate([hr-round_radius, 0, 0]) circle(r=round_radius, $fn=100);
    cylinder(r = hr-round_radius,h = round_radius, $fn=100);
    // cross cut
    // use head radius hr for relative notch proportions
    translate([0, 0, (hhi-1)/2-0.1]) cube([hr/4, hr2-hr3/4, hhi-1], center=true);
    translate([0, 0, (hhi-1)/2-0.1]) cube([hr2-hr3/4, hr/4, hhi-1], center=true);
    // thread
    translate([0,0,hhi-0.1]) thread_out(dia,hi+0.1);
    translate([0,0,hhi-0.1]) thread_out_centre(dia,hi+0.1);


  • Screw with no head (stud).
  • @param dia thread diameter (3=M3, 4=M4 etc.)
  • @param hi threaded rod height
    module nohead_screw(dia, hi) {
    hr = rolson_hex_bolt_dia(dia)/2;


I love this thread library, only concern is did you implement the ability to rotate the direction of the threads??, like Counter clockwise and clock wise, if you have could you point it out, many thanks. but if you cant then would you be able to add it in, then you would have the ultimate thread library.

you can simply use openscad mirror call to change direction :)

Really outstanding work on the thread library. It's both the fastest and most standard library I've found. There are a few others that are super precise, but take ages to render and are almost unusable in a preview.

Now I just need to wrap my head around your work.

Great work! :-) I love it!

Suggested code change for file "uploads_6f_12_f1_10_d2_ISOThread".

Line 160ish

module thread_in_ring(dia,hi,thk)
cylinder(r = (dia/2)+0.5,h = hi);
translate([0,0,-1]) cylinder(r = (dia/2)+0.1, h = hi+thk);


module thread_in_ring(dia,hi,thk)
cylinder(r = (dia/2)+0.5+thk,h = hi); //the change is add "+thk"
translate([0,0,-1]) cylinder(r = (dia/2)+0.1, h = hi+thk);

noticed my thread rings wouldn't change wall thickness.

Hi there,

I have been playing around with your library. I was having trouble getting usable prints on my Ultimaker 2, so I ended up making some tweaks. If you are curious, I have posted a remix to your remixes and I am hosting my version at: https://www.youmagine.com/designs/openscad-metric-nut-bolt-threads-library. There is also a patch file posted there.

The short of it is that when I render in OpenSCAD using your version, there are gaps between the thread segments and also between the bolt shaft and the threads. I use Cura as my slicer and it did not stich everything together, so the results were unusable. My version just tweaks some of the fudge factors / tolerance values to make it look and work right (for UM2 and Cura at least). My version also works with steel nuts and bolts.

All the gory details are at: http://umforum.ultimaker.com/index.php?/topic/4548-experiment-with-threads/?p=99628, if you are interested.

Anyway, I just wanted to say thank you very much for the great library! :) It works fantastically for me after the tweaks. If you care to share any thoughts on this, I would certainly appreciate the feedback.

Cool, as you can see from my photos, I had no such problem and my prints all work with steel nuts and bolts (the steel ones are black in the photos). I use Slic3r to get G-Code with 0 problems and print on my self built, 2 year old RepRap Metric Prusa.
But you are very welcome to use and change in any way you like as it is public domain license :-)

To be honest, the original library was my very first attempt at doing anything at all in OpenSCAD and I was more than shocked that there was so much interest in it. I later re-visited and knew there were some issues with tolerances, but could not tie it down.

As a complete change of subject, have you heard of Wamungo?

First of all thank you to both of you (TrevM and JustKrys). The library is so super useful! I was having a lot of problem too for the same problem that KustKrys reported that I was thinking about working on the library when I've read that "someone" already did it! Tried it and now works flawlessy! Wonderful!!! Thank you so much!
As additional information I'm slicing With Cura 2.6 beta. With normal settings all bits of the threads are separated (loooong time to print) but will joint togheter cause they are very close. But My printer is printing 0.2mm larger than expected (New Matter MOD-t) so I'm reducing the XY spacing with the super useful "Horizontal expansion" to -0.2 or -0.3. Using this the thread bits gets very separated and the result is not good.
Unfortunately it's my only way to respect correct dimensions in the thread, so JustKrys work saved me.

Hi TrevM. Thanks for responding.

I guess Sli3r and/or you Prusa are more tolerant of small spaces in the model. :)

I kept the same license on my tweaked version. Anything else seemed wrong.

No, I had never heard of Wamungo. I took a quick look, but nothing jumped out at me as being special. But I will check it out in more detail again. And it is always good to know about more places to get 3D models! :D Thanks for telling me about it.

FYI I'm also having these same problems using Simplify3D.

ERROR: CSG generation failed! (no top level object found)
Why do i get this error for every openscad model i try to use ?

Hi Tony,

ISOThread.scad is not supposed to be compiled / used on it's own, it's designed as a library.
Open up the file and near the top you will see //--demo functions-----------------------

Uncomment any 1 of these, e.g:


change to:


Now build again and you will see an M10 bolt 16 mm long

The idea is that you create your own design, put ISOThread.scad into the same directory as your .scad, then you use the lib in your .scad.


include ;


translate([20,0,0]) hex_bolt(8,10);


or for more control:


use ;


translate([20,0,0]) hex_bolt(8,10);


But this just does bolts, the library is so you can add threaded studs, or make jars with screw tops etc.
It's a library to be used any way you want in your OpenSCAD based designs.

Wow thanks man.
I use 3ds max for life and im starting to love openscad since i do programming for windows.

Be VERY careful, damned thing is highly addictive. Basically it is writing software that describes hardware, press 1 button and see it in front of you in glorious 3D, press a few more buttons and hold your object in your hands.
I've done embedded and Windows SW for last 15 years or so, SW is a bit like electricity, you can't touch it, you can only see it's effects, OpenSCAD is the missing link, be scared, be very scared, you are hooked.

Hoping someone may be able to answer a question for me... When printing an M7 bolt and nut, I am finding that they seem to mesh pretty well. Unfortunately, I am not seeing the same result when I modify the size for the head of the bolt and nut. I am keeping the diameter of the threaded parts at M7, but I added [7,20] and [7,10] to the head lookup tables for both the nut and bolt sections.

Here is that section for the Nut (it is also the same for the Bolt):

// function for Rolson hex nut diameter from thread size
function rolson_hex_nut_dia(dia) = lookup(dia, [
// function for Rolson hex nut height from thread size
function rolson_hex_nut_hi(dia) = lookup(dia, [

Is there any reason why now the bolt threaded diameter seems to be smaller (or the nut threaded hole larger)? When printing the nut and bolt, the threads do not mesh well and the nut is very loose on the bolt threads. I have changed nothing else in the OpenSCAD code except for the head size changes noted above. BTW, I needed "chunky" heads on the nut and bolt so I could finger tighten them.

Any guidance would be greatly appreciated! Thank you very much for providing this library, it is VERY useful!

You don't need to use the functions, you can do anything you like.

use ;




The cylinder command allows you to fully specify the head any way you want, the r= lets you specify radius of head, the h= lets you specify thickness of head, the $fn= lets you specify how many sides you want on head (usually 6).

When using "thread_out" and "thread_out_center" with a setting of 52mm, I was getting an "Object isn't a valid 2-manifold! Modify your design." error when exporting to STL. I fixed it by setting my thread_out_center to 52.3mm.

Thanks, good work! I made a little change, because I wasn't getting any behaviour I could use from the thk parameter to thread_in_ring(), and I was expecting it to alter the thickness of the ring. After making this change it worked as I needed:

--- ISOThread-orig.scad 2014-05-27 00:33:36.173015497 +0200
+++ ISOThread.scad      2014-05-27 00:29:25.329026680 +0200
@@ -162,10 +162,10 @@
 module thread_in_ring(dia,hi,thk)
-               cylinder(r = (dia/2)+0.5,h = hi);
-               translate([0,0,-1]) cylinder(r = (dia/2)+0.1, h = hi+thk);
+               cylinder(r = (dia/2)+0.5 + thk,h = hi);
+               translate([0,0,-1]) cylinder(r = (dia/2)+0.1, h = hi+2);

Very well spotted and fixed :-)
I actually found this myself about an hour after publishing, I decided not to publish the fixed version purely to see if anyone else found it.
Many congratulations, you are the first to find it in over a month with 631 views, 199 downloads

Haha, thanks! I wasn't sure I was using it like you intended, but I thought I'd share because I thought this made more sense. ;)
By the way, it would also be really nice if there were a generic function to make a hex bolt head/nut with configurable size, then I could use that and cut the holes I needed to make a part with custom thread or even no thread in a particular section.

um, try:


you specify r=radius, h=height, $fn=number of faces,

or have I misunderstood?