8.1 Libraries and JSCAD Introduction
SLO 3
Describe, design, implement, and test structured programs using currently accepted methodology.
Learning Objectives
By the end of this section, you will be able to:
- explain what a library is and how JSCAD turns code into 2D and 3D models;
- describe the two JSCAD web apps and why every function works the same in both;
- read a
JSCAD → module → fnanchor and find the matching documentation page; - render your first solid by writing three lines of JSCAD;
- go from "I need a rounded box" to the right documentation page using the anchor;
- find which library module holds a function for a job you have in mind.
JSCAD is a JavaScript library for parametric 2D and 3D CAD design. Instead of dragging shapes around in a drawing program, you describe a model as JavaScript code that returns geometry. The engine is @jscad/modeling (the @jscad/modeling@2.13.0 package this book cites) plus @jscad/regl-renderer for the 3D viewport.
A drawing program remembers the shapes you drew, but not how you made them. With parametric CAD, the code is the recipe. Change one number and the whole model rebuilds — that is the power you will use all chapter.
JSCAD ships with this book. The library files are served from the book itself rather than fetched from a CDN, so the JSCAD examples in these chapters keep working without an internet connection, and they cannot break because an outside service changed. The version you are reading against is pinned: @jscad/modeling@2.13.0.
Every JSCAD anchor in this book follows the form JSCAD → <module> → <fn>, matching a real JSDoc page at https://openjscad.xyz/docs/module-modeling_<module>.html#.<fn>. For example, JSCAD → primitives → cube is https://openjscad.xyz/docs/module-modeling_primitives.html#.cube.
The JSCAD → module → fn arrow is a tiny address. It tells you which module to look in and which function to grab, so you can jump straight to the exact documentation page instead of hunting.
Two UIs, one library
jscad.app(https://jscad.app/) — the environment this course actually uses. An independent, open-source (MIT) reimplementation of the OpenJSCAD web app, built onjscadui(https://github.com/hrgdavor/jscadui). It supports npm imports, ES modules, and TypeScript, and keeps its background worker alive between parameter changes.openjscad.xyz— the original web app and the home of the hosted API docs used throughout this book. Its own live editor is a second UI over the exact same@jscad/modelinglibrary.
Because both apps run the same library, every function documented in this book works identically in either one.
jscad.app and openjscad.xyz look like different websites, but they are just two front doors into the same @jscad/modeling engine. Learn the library once and you can work in either app.
When a function is documented in this book, it behaves the same in both apps. That is why the book can point you at either one — the code you write is portable.
One more thing before the first line of code, because it is what makes the rest of this chapter read straight. Everything here runs on @jscad/modeling — but you will not usually write its names. You will write reSHape: twelve short words laid over the library, one for each shape and move you reach for most.
| you write | the library calls it |
|---|---|
box(w, d, h) |
cuboid({ size: [w, d, h] }) |
rect(w, h) |
rectangle({ size: [w, h] }) |
disc(r) |
circle({ radius: r }) |
ball(r) |
sphere({ radius: r }) |
tube(r, h) |
cylinder({ radius: r, height: h }) |
cone(r, h) |
cylinderElliptic({ startRadius: [r, r], endRadius: [0, 0], height: h }) |
ring(ringRadius, tubeRadius) |
torus({ outerRadius: ringRadius, innerRadius: tubeRadius }) |
poly(points) |
polygon({ points }) |
extrude(h, shape) |
extrudeLinear({ height: h }, shape) |
revolve(shape) |
extrudeRotate({}, shape) |
turn(degrees, shape) |
rotate — but in degrees, and about the shape's own middle |
sit(shape) |
align — drops the shape onto the floor |
The measurements a shape needs go in as plain numbers; anything extra rides in curly braces after them, as in box(20, 8, 3, { roundRadius: 1 }). Everything the library has that reSHape has no word for — translate, union, subtract, hull, every measurement — you call by its own name, unchanged. Nothing is hidden and nothing is renamed: reSHape only adds words, and the right-hand column above is what you write the day you take a model to jscad.app.
So the anchor JSCAD → primitives → circle tells you which module holds the flat-circle function, and disc is the word you write to reach it. Here it is — a flat disk, eight units across the radius:
Your first shape
Everything above is groundwork. Now make something. A JSCAD script is just an expression that produces geometry — one function call that returns a solid. The viewer in the editor draws whatever your code makes. When you change the code and press Run, the model rebuilds from your new numbers.
You had never seen disc written out before, but the anchor told you which module holds the function behind it, and it behaved as promised. That is the whole point of the notation — it turns "there must be a way to do this" into a place to look.
Here is a whole JSCAD script. It is already running — the cube below it is what this one line produced:
Drag the model to turn it, scroll to zoom, and use the handles in the corner to pan or reset the view. Then change 10 to 20 and press Run: same line, bigger cube. That is the whole loop you will use for the rest of this book — write a number, run it, look at what you got.
There is no setup, no window to open, no file to save. box(10, 10, 10) produces a solid, and the viewer draws it. Everything else in these chapters is that same idea with more interesting shapes.
A cube is the simplest solid there is to make. box takes three numbers — width, depth, height — so three equal numbers is a cube; underneath it is JSCAD → primitives → cuboid. Each comment below is one line for you to write. Press Run when you are done.
Solution
You should see a solid cube. Change all three numbers to 20 and run it again — the same shape, twice as wide, because box builds from whatever numbers you hand it.
There is no save button and no export step here. The geometry in the viewer is the direct result of running the expression — change a number, re-run, and the model rebuilds. That is parametric CAD in its smallest form.
ball takes one number, a radius, where box takes three. Swapping one primitive for another is a one-line change.
Solution
You should see a solid ball. Unlike the cube, you can orbit it in every direction and it looks the same from all sides. Bump the radius to 9 and the ball grows.
The whole point of parametric CAD is that changing a number rebuilds the model. Build the 10-unit cube, then halve the numbers and watch what the viewer does.
Solution
The 10-unit cube is twice as tall, wide, and deep as the 5-unit one — its volume grows by a factor of eight. Notice that all three numbers had to change together; that is what keeps it a cube.
Finding the function you need
The library is organised into modules, and each module groups one kind of job. When you think "there must be a function for this," start with the kind of thing you want, then open the matching module in the reference below.
| You want to… | Open this module |
|---|---|
| Make a flat or solid shape | primitives |
| Move, turn, or flip something | transforms |
| Cut a hole or combine shapes | booleans |
| Give a 2D outline depth or spin it into a solid | extrusions |
| Measure a part's size, centre, or volume | measurements |
| Blend two shapes into one smooth outline | hulls |
| Put letters on the model | text |
The library, module by module
The library is organised into modules, each grouping one kind of job. A function's module is the first half of its anchor — JSCAD → primitives → cube means cube lives in the primitives module. For every function this book teaches, the table gives a one-line description. Functions listed also in this module exist in the library but are not taught in this book; you can look them up on the JSDoc page when you need them.
Each module below pairs its table with a tiny working example. Run it, poke at a number, run it again. That is all this section asks of you — the real teaching happens from section 8.2 on.
primitives — the basic shapes
The building blocks: flat and solid shapes you place in the model. 13 of 21 functions are taught.
| function | what it does | you write |
|---|---|---|
circle |
a flat circle (2D) | disc(r) |
cube |
a solid box with equal edges | box(s, s, s) |
cuboid |
a solid box with three edge lengths | box(w, d, h) |
cylinder |
a solid can with radius and height | tube(r, h) |
ellipse |
a flat oval (2D) | — |
polygon |
a flat shape from any list of points (2D) | poly(points) |
rectangle |
a flat box (2D) | rect(w, h) |
roundedCuboid |
a solid box with rounded edges | box(w, d, h, { roundRadius }) |
roundedCylinder |
a solid can with rounded rims | tube(r, h, { roundRadius }) |
roundedRectangle |
a flat box with rounded corners (2D) | rect(w, h, { roundRadius }) |
sphere |
a solid ball | ball(r) |
star |
a flat multi-pointed star (2D) | — |
torus |
a solid donut shape | ring(ringRadius, tubeRadius) |
Also in this module: arc, cylinderElliptic, ellipsoid, geodesicSphere, line, polyhedron, square, triangle.
A donut next to a squishy tablet — two shapes you have not met yet. ring is the donut, and a roundRadius on a box wears its corners off:
Some are flat (2D, like disc and rect) and some are solid (3D, like box and ring). The flat ones are the raw material for the extrusions module later — you will see why in a moment.
ring takes two radii and they do different jobs: the first is how far out the tube travels, the second is how thick that tube is. Hold the first still and change the second.
Solution
A thinner tube on the same travel circle: ring(12, 6) is 36 across with a 12-wide hole, and ring(12, 2) is 28 across with a 20-wide hole. Thinning the tube widens the hole and shrinks the outside at the same time, because both edges are measured from that same travel circle. Drag it around to see the difference.
Using the primitives table above, write a call that renders a can 4 units across and 15 units tall. Pick the function yourself.
Solution
Step 1 — pick the function. "A can" is a cylinder, so the table points at cylinder — and the reSHape word for it is tube.
Step 2 — read what it needs. tube takes a radius and a height, in that order. "4 units across" is a diameter, so the radius is 2.
Step 3 — write the call.
Answer: tube(2, 15) — a can 4 wide and 15 tall.
transforms — moving, turning, and flipping shapes
Operations that reposition or reshape an existing solid. 8 of 22 functions are taught.
| function | what it does | you write |
|---|---|---|
align |
line shapes up along an axis | sit(shape), for the floor |
center |
move a shape to the origin | — |
mirror |
flip a shape across a plane | — |
rotate |
turn a shape around an axis | turn(degrees, shape) |
rotateX |
turn a shape around the X axis | — |
rotateZ |
turn a shape around the Z axis | — |
scale |
stretch or shrink a shape | — |
translate |
move a shape to a new position | — |
Also in this module: centerX, centerY, centerZ, mirrorX, mirrorY, mirrorZ, rotateY, scaleX, scaleY, scaleZ, transform, translateX, translateY, translateZ.
A transform takes a shape and hands you back a changed copy. This one builds a flat card, tips it, then slides it across the floor:
Each one takes the previous result as its input. turn tips the card, and translate then moves the tipped card — not the original. Change the angle and the moved card shifts its whole attitude.
turn takes plain degrees, which is the one place reSHape does not simply rename a library call: rotate works in radians, and it swings a shape around the world origin rather than turning it where it stands. Both facts matter later; for now, 30 means 30°.
Solution
The card is steeper — a bigger angle, a stronger tip. Play with the translate numbers too and watch the card slide.
Build a ball of radius 4 and move it 10 units along the X axis. Use the transforms table to pick the function.
Solution
Step 1 — build the shape first. A transform needs something to act on, so start with ball(4).
Step 2 — pick the transform. "Move a shape to a new position" is translate.
Step 3 — hand it the offset. translate takes [x, y, z], so moving 10 along X is [10, 0, 0].
Answer: translate([10, 0, 0], ball(4)) — the same ball, sitting 10 units to the right. translate is the library's own name, kept as it is: reSHape has no shorter word for it.
booleans — combining and cutting shapes
Operations that join shapes or carve one shape out of another. 3 of 5 functions are taught.
| function | what it does |
|---|---|
intersect |
keep the volume where two shapes overlap |
subtract |
cut one shape out of another |
union |
fuse shapes into one solid |
Also in this module: minkowski, scission.
subtract carves one shape out of another. Here a tall tube punches a hole straight through a flat slab:
subtract(base, pin) means "start with base, and remove every part of it that overlaps pin." Swap the arguments and you are left with the pin minus the slab — a very different part. Order matters.
Sometimes you want a part with a hole in it — a washer, a bracket, a plate with a bolt opening. That is a two-step recipe: build the solid, then subtract the shape you want removed. Build a flat plate with a hole by subtracting a disc from a rect.
Solution
You should see a flat square with a circular hole cut through the middle. That is the subtract pattern you will use over and over: the part you keep first, the part you remove second.
subtract and union take the same two shapes and hand back opposite results. Swapping the function name is the entire change — everything else stays put.
Solution
union fuses the two shapes into one solid instead of cutting the hole — you get a slab with a pin standing on top of it. Same two shapes, opposite result: subtract removes, union merges.
Keep only the volume where a cube of edge 10 and a ball of radius 6 overlap. Pick the boolean from the table above.
Solution
Step 1 — read the wording. "Keep only the volume where two shapes overlap" is the table's description of intersect.
Step 2 — build both shapes. box(10, 10, 10) and ball(6), both centred on the origin by default.
Step 3 — combine them.
Answer: intersect(box(10, 10, 10), ball(6)) — a cube with its corners rounded off by the ball, because only the shared volume survives.
extrusions — giving 2D outlines depth
Operations that build a solid from a flat (2D) outline. 3 of 6 functions are taught.
| function | what it does | you write |
|---|---|---|
extrudeLinear |
pull a flat outline straight out into a solid | extrude(h, shape) |
extrudeRectangular |
extrude an outline with square walls | — |
extrudeRotate |
spin a flat outline around an axis into a solid | revolve(shape) |
Also in this module: extrudeFromSlices, extrudeHelical, project.
This is where flat shapes grow a third dimension. A small four-cornered outline, spun around an axis, becomes a rounded pot:
revolve takes a flat outline and spins it all the way around an axis, sweeping out a solid as it goes. Change segments and you change how smooth the curve is — fewer segments, more facets.
A flat rect is just a 2D outline — you cannot hold it. Pull it straight up into a solid block with extrude, whose first number is the height. Write the block from a flat card.
Solution
You should see a flat box with a rectangular footprint — the 2D card pulled up 5 units. Same outline, but now it is a solid you can measure and cut.
The vase has no height of its own — its height lives in the outline you spin. To make it taller you edit the points, not the revolve call.
Solution
The wall is taller, so the spun pot is taller too. The outline you feed in IS the shape of the final solid — change a point, change the vase.
Turn a flat disc of radius 6 into a solid puck 2 units thick. Use the extrusions table to pick the function.
Solution
Step 1 — start flat. disc(6) is a 2D outline, which is what every extrusion needs as input.
Step 2 — pick the extrusion. "Pull a flat outline straight out into a solid" is extrudeLinear, and the reSHape word for it is extrude.
Step 3 — set the thickness. extrude takes the height first, so 2 units thick is extrude(2, outline).
Answer: extrude(2, disc(6)) — a solid puck, 12 across and 2 thick.
measurements — reading size and position
Operations that report numbers about a part (its size, centre, or volume) rather than changing it. 6 of 12 functions are taught.
| function | what it does |
|---|---|
measureArea |
report a shape's surface area |
measureBoundingBox |
report the smallest box that fits the shape |
measureAggregateBoundingBox |
report the box that fits several shapes together |
measureCenter |
report a shape's centre point |
measureDimensions |
report a shape's width, height, and depth |
measureVolume |
report a solid's enclosed volume |
Also in this module: measureAggregateArea, measureAggregateEpsilon, measureAggregateVolume, measureBoundingSphere, measureCenterOfMass, measureEpsilon.
These functions answer questions instead of drawing shapes. Here measureVolume and measureDimensions report on a box that is still sitting in the scene, so you can see it:
The viewer draws crate; the vol and dims numbers show up in the console. Here vol is 6000 (10 × 20 × 30) and dims is [10, 20, 30]. Measure your own shapes to check your arithmetic.
A measurement is not a shape — it is a number the library reads back off one. Change the crate and the reported volume changes with it, which makes measureVolume a way to check your own arithmetic.
Solution
The crate is slimmer and vol is now 3600 — one dimension shorter, a smaller box. Watch how the reported number tracks exactly the number you changed.
hulls — wrapping shapes in a smooth outline
Operations that wrap a set of shapes with a single smooth outer surface. 2 of 4 functions are taught.
| function | what it does |
|---|---|
hull |
wrap several shapes in one convex outline |
hullChain |
wrap shapes end to end into a chain |
Also in this module: hullPoints2, hullPoints3.
hullChain stretches a skin over a row of shapes, fusing them into one smooth lump. Two balls become a single rounded blob:
The result hugs the outside of both shapes and fills the dip between them. Move the balls further apart and the lump stretches into a capsule — the hull always wraps whatever you give it.
hullChain does not care what sizes you feed it — it wraps whatever is there. Grow one of the two balls and the skin stretches to cover it.
Solution
The right bulge is bigger because its ball is bigger. The hull smooths over whatever sizes you give it.
text — putting letters on the model
Operations that turn a string of text into geometry. 2 of 2 functions are taught.
| function | what it does |
|---|---|
vectorChar |
turn a single character into outline geometry |
vectorText |
turn a whole string into outline geometry |
Also in this module: none.
vectorText turns a letter into outline points, and path2.fromPoints turns those points into a shape you can extrude up into a solid letter:
A letter is a shape with a boundary, exactly like the poly you extruded earlier. Feed the letter's points to extrude and it becomes a solid you can place, cut, and combine — a 3D printed nameplate in the making.
The letter is just a string you hand to vectorText. Everything after it — the points, the closed path, the extrusion — stays exactly the same no matter which character you pick.
Solution
Now it is a solid H. Swap in any single letter and watch the model follow.
colors — tinting parts of a model
Operations that assign a colour to a shape so the viewer can tell parts apart. None are used in this book yet; 12.2 covers colour.
Also in this module: colorize, colorNameToRgb, hexToRgb, hslToRgb, hsvToRgb, hueToColorComponent, rgbToHex, rgbToHsl, rgbToHsv.
expansions — growing or shrinking outlines
Operations that push a flat outline outward or inward. None are used in this book yet.
Also in this module: expand, offset.
utils — small helpers
Tiny helper functions that convert units or sort lists for you. None are used in this book yet.
Also in this module: areAllShapesTheSameType, degToRad, flatten, fnNumberSort, insertSorted, radiusToSegments, radToDeg.
modifiers — adjusting how shapes are stored
Operations that change a shape's internal representation (for example, to smooth or simplify it). None are used in this book yet.
Also in this module: generalize, snap, retessellate.
minkowski — blending shapes into a rounded shell
An operation that grows a shape by the outline of another shape, producing rounded, blended forms. None are used in this book yet.
Also in this module: minkowskiSum.
Reading the documentation
The anchor notation only helps if you can go from "I need a rounded box" to the right page. The move is always two steps: find the module, then the function. Primitives live in primitives, transforms in transforms, and boolean operations in booleans. Once you know the module, the → fn part names the exact function, and the URL builds itself. The tables above are the quick answer for the functions this book teaches; the JSDoc page is where you go for full option lists.
| What you want to do | JSCAD anchor | you write |
|---|---|---|
| Build a solid box | JSCAD → primitives → cube |
box(w, d, h) |
| Build a rounded solid | JSCAD → primitives → roundedCuboid |
box(w, d, h, { roundRadius }) |
| Move a shape to a new spot | JSCAD → transforms → translate |
translate([x, y, z], shape) |
| Combine two shapes | JSCAD → booleans → union |
union(a, b) |
You never search the whole site. You pick the module from the kind of thing you want (a shape, a move, a combination), then the function from its name. JSCAD → primitives → roundedCuboid tells you the page is module-modeling_primitives.html#.roundedCuboid — no hunting.
Problem Set
Problem 1. In your own words, explain what it means for a JSCAD model to be parametric. Give one reason a designer would prefer a parametric model over a drawing made by hand.
Problem 2. Name the two JSCAD web apps described in this section and state one thing they have in common.
Problem 3. Write the JSCAD → module → fn anchor for the cube function and give the full documentation URL it points to.
Problem 4. Write a reSHape call that renders a cube with edge length 6.
Problem 5. Write a reSHape call that renders a ball with radius 3.
Problem 6. Write the JSCAD → module → fn anchor for the scale function and give the full documentation URL it points to.
Problem 7. Write the JSCAD → module → fn anchor for the subtract function and give the full documentation URL it points to.
Problem 8. Write the JSCAD → module → fn anchor for the circle function and give the full documentation URL it points to.
Problem 9. In your own words, explain the difference between a parametric model and a drawing made by hand. Which one rebuilds when you change a single value?
Key Terms
parametric CAD — a way of designing models where the geometry is described by code and parameters, so changing a value rebuilds the whole model.
library — a collection of ready-made code (here, JavaScript functions) you can call from your own program.
CDN — a content delivery network that serves a library to your browser at runtime over the internet.
anchor — the JSCAD → module → fn form used in this book to point to a specific function's documentation page.
primitive — a basic built-in shape (such as cube or sphere) that JSCAD can create.
module — the part of the library a function belongs to (such as primitives, transforms, or booleans).
transform — an operation that moves, rotates, resizes, or flips an existing shape.