Reference

OpenSCAD libraries: BOSL2 and MCAD for threads, gears and screws

OpenSCAD libraries are collections of ready-made modules that you load with include or use. The PrintPal CAD Agent bundles the two most popular ones, BOSL2 and MCAD, so a line like include <BOSL2/std.scad> works in the browser with nothing to install. This page shows how to load them, the modules worth knowing, and the license terms for each.

7 min read Updated October 2026 Intermediate OpenSCAD reference · 8 of 8
In short
  1. BOSL2: include <BOSL2/std.scad> first, then the add-on file you need, such as threading.scad, screws.scad or gears.scad.
  2. MCAD: use <MCAD/file.scad>, as its README recommends.
  3. BOSL2 is beta: names and arguments still change, so match examples to the bundled version, 2.0.741.
  4. In the PrintPal editor, put slider parameters above the include lines.

BOSL2 and MCAD at a glance

BOSL2MCAD
What it isA large modern library: rounded shapes, attachments, threads, screws, gears, paths and mathThe older library that ships with desktop OpenSCAD: gears, bolts, motors, bearings, regular shapes
Load withincludeuse
Bundled version2.0.741, snapshot of 20 May 2026Snapshot of 20 May 2026
Files and download size56 .scad files, about 4.3 MB raw or 0.96 MB gzipped42 .scad files, about 224 KB raw or 44 KB gzipped
StatusBeta, actively developedStable, rarely changes
LicenseBSD-2-ClauseLGPL 2.1
NeedsOpenSCAD 2021.01 or laterAny recent OpenSCAD

Load BOSL2 with include

std.scad pulls in the core: shapes, attachments, rounding, distributors such as xcopies(), masks and the math helpers. Bigger topics live in separate files that you include after it:

FileAdds
BOSL2/std.scadcuboid(), cyl(), attach(), diff(), xcopies(), right() and the rest of the core
BOSL2/threading.scadthreaded_rod(), threaded_nut(), trapezoidal and acme threads
BOSL2/screws.scadscrew(), nut(), screw_hole() by name, such as "M3" or "#8-32"
BOSL2/gears.scadspur_gear(), rack(), gear_dist() and other gear types

use <BOSL2/std.scad> does not work. BOSL2's modules read constants such as TOP and BOT, and use does not import variables, so the render stops with errors. Always include BOSL2. The difference is explained in modules and functions.

BOSL2 is beta. Its README says the code is still being reorganized, and names and arguments do change between versions. An example written for a newer BOSL2 can fail on the bundled 2.0.741, and old tutorials may use modules that have since been renamed. When something fails, check the console: an unknown argument is reported as a warning.

Which opening loads BOSL2's threads correctly?

  1. use <BOSL2/threading.scad>
  2. use <BOSL2/std.scad> then include <BOSL2/threading.scad>
  3. include <BOSL2/std.scad> then include <BOSL2/threading.scad>

BOSL2 add-on files expect the core from std.scad to be included first, and every BOSL2 file needs include so its constants come along.

Rounded boxes with cuboid()

include <BOSL2/std.scad>
cuboid([40, 20, 10], rounding=3, edges="Z", anchor=BOT);   // exactly 40 × 20 × 10 mm

cuboid() takes the finished size directly. edges="Z" rounds only the vertical edges; leave it out to round every edge. anchor=BOT puts the bottom face on the bed. Doing the same with minkowski() means shrinking the input yourself, as shown in transformations.

Attach features with attach() and diff()

BOSL2's attachments place one shape relative to a face of another, so you never compute coordinates. attach(TOP, BOT) puts the child's bottom on the parent's top. Inside diff(), anything tagged "remove" is subtracted:

include <BOSL2/std.scad>

diff()
  cuboid([50, 30, 5], rounding=3, edges="Z", anchor=BOT) {
    attach(TOP, BOT) cyl(d=12, h=15, rounding2=2);        // a boss on the top face
    attach(TOP) xcopies(spacing=38) tag("remove") cyl(d=3.4, h=20); // two holes
  }

BOSL2 threads: threaded_rod() and threaded_nut()

include <BOSL2/std.scad>
include <BOSL2/threading.scad>
$slop = 0.1;   // calibrate for your printer; internal threads get 4 × $slop clearance

threaded_rod(d=10, l=30, pitch=1.5, blunt_start=true, anchor=BOT, $fn=64);
right(25)
  threaded_nut(nutwidth=17, id=10, h=8, pitch=1.5, anchor=BOT, $fn=64);

$slop is BOSL2's printer-fit allowance. It defaults to 0, and internal threads get 4 × $slop of extra clearance, so small values matter: BOSL2's own examples use 0.05 to 0.1. To find yours, print the Slop Calibration part from the constants.scad docs and set $slop after the include lines.

Screws, nuts and screw holes by name

include <BOSL2/std.scad>
include <BOSL2/screws.scad>

screw("M3", length=12, head="socket", drive="hex", anchor=BOT);
right(10) nut("M3", anchor=BOT);

screws.scad knows standard metric and UTS sizes, so "M3" gives the right pitch and head. Real screws are cheap, though: for printed parts the most useful module is often screw_hole(), cut with diff():

include <BOSL2/std.scad>
include <BOSL2/screws.scad>
diff()
  cuboid([30, 20, 8], anchor=BOT)
    attach(TOP) tag("remove") screw_hole("M3", length=10, head="flat", anchor=TOP);   // countersunk M3 hole from the top

Gears: spur_gear() and gear_dist()

include <BOSL2/std.scad>
include <BOSL2/gears.scad>

gear_mod = 2;
teeth1 = 24;
teeth2 = 12;
d = gear_dist(mod=gear_mod, teeth1=teeth1, teeth2=teeth2);   // 36.56 mm, not 36

spur_gear(mod=gear_mod, teeth=teeth1, thickness=6, shaft_diam=5,
          backlash=0.1, gear_spin=-90);
right(d)
  spur_gear(mod=gear_mod, teeth=teeth2, thickness=6, shaft_diam=5,
            backlash=0.1, gear_spin=90 - 180/teeth2);

By default BOSL2 profile-shifts small gears to avoid weak, undercut teeth (below 17 teeth at the standard 20° pressure angle). That changes the centre distance, so a 24-tooth and a 12-tooth module 2 pair sits 36.56 mm apart, not the textbook 36 mm. Always space gears with gear_dist(). The gear_spin values rotate the teeth so they interlock, and backlash adds running clearance.

spur_gear() has no chamfer argument, and BOSL2 has no module called gear(); both appear in older examples online. The examples page has a complete printable gear pair.

MCAD: gears, bolts and regular shapes

MCAD is smaller and older. Load each file with use. Its gear module measures circular_pitch in millimetres along the pitch circle, so the pitch diameter is teeth × circular_pitch ÷ π. A value of 2 * PI is module 2:

use <MCAD/involute_gears.scad>

// circular_pitch is in mm: 2 × PI = module 2, so pitch diameter = 24 × 2 = 48 mm
gear(number_of_teeth=24, circular_pitch=2 * PI, pressure_angle=20,
     gear_thickness=6, rim_thickness=6, hub_thickness=6, bore_diameter=5);

MCAD's default pressure angle is 28°; set it to 20 to mesh with standard and BOSL2 gears. Beware old snippets that pass circular_pitch=300: with 24 teeth that is a gear about 2.5 metres across.

use <MCAD/nuts_and_bolts.scad>

difference() {
  cube([20, 20, 8]);
  translate([10, 10, 8]) rotate([180, 0, 0]) boltHole(3, length=10);  // M3 hole + head recess
}
use <MCAD/regular_shapes.scad>
linear_extrude(height=5) hexagon(radius=10);

Sliders and include lines in the PrintPal editor

The editor builds its sliders from the plain name = value; lines at the top of your file, and it stops reading at the first include, use, module or shape. Put your parameters first and the libraries after them, or you will get no sliders at all:

// Box length (mm) [20:1:120]
box_l = 40; // [20:1:120]
// Box width (mm) [10:1:80]
box_w = 20; // [10:1:80]
// Corner radius (mm) [0:0.5:8]
corner_r = 3; // [0:0.5:8]
include <BOSL2/std.scad>
cuboid([box_l, box_w, 10], rounding=corner_r, edges="Z", anchor=BOT);

The comment line above each parameter becomes its slider label and range in PrintPal. The trailing comment is the range format desktop OpenSCAD's Customizer reads, so this layout works in both. The parametric design guide covers the full layout.

How libraries load in the browser

  1. Before each render, the editor looks for include <BOSL2/…>, use <MCAD/…> and similar lines in your code.
  2. The first time a library is mentioned, its bundle (one JSON file holding every .scad file) is downloaded and kept in memory for the rest of the session.
  3. Every file from the bundle is written into OpenSCAD's in-browser file system at /BOSL2/… or /MCAD/…, so the include resolves exactly as on desktop.

Need a library that is not bundled? Only BOSL2 and MCAD are available in the browser, and you cannot add other library files. Paste the modules you need into your own file, keeping their license notices, or work in desktop OpenSCAD, where any library in your library folder works.

Versions and updates

The bundles are copied from upstream at build time and refreshed from time to time. Each one records its snapshot date, which you can check yourself:

curl -s https://printpal.io/static/openscad/libraries/bosl2-bundle.json \
  | jq '{name, snapshot_date, source, license, files: (.files | keys | length)}'

BOSL2 moves quickly, and upstream has had several releases since this snapshot. If a BOSL2 wiki example uses something the bundled 2.0.741 lacks, that is the likely reason.

Licenses and attribution

BOSL2: BSD 2-Clause

FieldValue
Upstreamgithub.com/BelfrySCAD/BOSL2
Bundle/static/openscad/libraries/bosl2-bundle.json
LicenseBSD 2-Clause: full text
CopyrightCopyright (c) 2017-2019, Revar Desmera. All rights reserved.
BSD 2-Clause License

Copyright (c) 2017-2019, Revar Desmera
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

MCAD: GNU LGPL 2.1

FieldValue
Upstreamgithub.com/openscad/MCAD
Bundle/static/openscad/libraries/mcad-bundle.json
LicenseGNU LGPL 2.1: full text
CopyrightVarious authors, named in each file's header. Some files carry their own terms, for example LGPL 3 or later, or more permissive licenses.

PrintPal serves the MCAD files unmodified, with every copyright notice and license header intact, and the complete source is in the bundle above and on GitHub. You can run your own modified MCAD in desktop OpenSCAD at any time.

Both licenses govern the library code. If you redistribute library files, keep their notices. Shapes you make by calling library modules are your own designs in most cases, but this page is not legal advice.

Ask the CAD Agent to use the libraries

The CAD Agent knows the bundled libraries. Naming the module and the fit you want gets you closest on the first try.

Using BOSL2, make an M8 x 1.25 threaded rod 40 mm long and a matching hex nut 13 mm across flats and 6.5 mm tall, side by side. Set $slop = 0.1 after the includes and keep the thread size and length as parameters.

Using BOSL2 spur_gear, make a meshing pair of module 2 gears with 30 and 15 teeth, 6 mm thick, with 5 mm shaft holes. Space them with gear_dist() and phase them so the teeth interlock.

AI tool · free to tryCAD AgentThreads, screws and gears from BOSL2 in plain English, with a live preview and STL/3MF export.Open tool

Frequently asked questions

Is BOSL2 included with OpenSCAD?

No. Desktop OpenSCAD ships with MCAD, but BOSL2 has to be downloaded from GitHub and copied into your OpenSCAD library folder (File, Show Library Folder). The PrintPal CAD Agent bundles both, so they work in the browser with nothing to install.

Should I use include or use for BOSL2?

include. BOSL2's modules rely on constants such as TOP and BOT that use does not import, so use with BOSL2/std.scad fails. Include std.scad first, then any add-on file such as threading.scad, screws.scad or gears.scad.

How do I make threads in OpenSCAD?

With BOSL2, include std.scad and threading.scad, then call threaded_rod(d=10, l=30, pitch=1.5) and threaded_nut(nutwidth=17, id=10, h=8, pitch=1.5). Set $slop for your printer so printed nuts fit: internal threads get 4 x $slop of extra clearance.

Why do BOSL2 examples from the internet fail?

BOSL2 is still in beta and its function names and arguments change between versions. Compare the example with the BOSL2 wiki and the version you run (2.0.741 in the PrintPal editor), and read the console: an unknown argument shows up as a warning.

Can I sell models made with BOSL2 or MCAD?

Both licenses are about the library code. BOSL2's BSD-2-Clause license is permissive and allows commercial use. MCAD's LGPL 2.1 also allows commercial use, with conditions on sharing changes to the library itself. If you redistribute the library files, keep their license notices. For anything high-stakes, ask a lawyer.

Sources & further reading