A 3D viewer is great on a laptop. On the living-room floor, with a kid and a pile of bricks, you want paper. So every guide on Mister Blocks prints as a real instruction booklet, comes as a PDF, and works offline once you've opened it.
This is how that works, with no PDF library and no server-side rendering of 3D.
The booklet is just a web page
/builds/<name>-lego-build/print lays the guide out like a LEGO booklet: a cover, one step per page (the number, a blue box of the pieces it needs, what to do, and the model so far as big as the page allows), then the parts list.
The trick that makes it look the same on screen and on paper: everything inside a page is sized in cqw, 1% of the sheet's width (CSS container query units). The sheet on screen and the sheet in the print dialog are the same shape, so the text and pictures land in the same places.
Paper size is a toggle. US Letter landscape is the default and A4 is one click away. The toggle swaps an @page rule and a class on <html>, and remembers your choice.

Ladder 9 Fire Engine: 127 pieces, 15 steps, 18 printed pages. More LEGO trucks.
Every picture is drawn in your browser
There are no stored step images. The print page runs the same three.js viewer off screen and takes snapshots:
- The cover: the finished model in its own lighting, framed a little wider than tight.
- Each step: the model so far, on white, framed on what's built so far. The camera is never closer than 60% of the distance that fits the whole model, so step 1 (four plates) doesn't fill the page like a close-up. Then the white edges are cropped off.
- Each kind of piece: drawn on its own, all from the same camera distance, so a 1×1 plate looks small next to a 2×4 brick, just like in a real booklet.
Wheels are the exception: they're drawn flat in 2D, because the viewer can't draw a wheel without the plate it sits on.
PDFs: headless Edge and a page count
A PDF is the print page printed by headless Edge:
msedge --headless=new --no-pdf-header-footer --virtual-time-budget=<ms> --print-to-pdf=out.pdf <url>?paper=a4 The time budget grows with the model (40 s plus a bit per piece and per step), because a 1,400-piece sculpture takes a while to draw 120 times.
Before anything is uploaded, the script counts the pages in the PDF: it should be 1 cover + 1 page per step + 1 page per 40 kinds of piece. If the count is off, a picture didn't finish drawing, so that PDF is skipped instead of shipping a booklet with a blank step. Good ones go to Cloudflare R2, Letter and A4, in English and Ukrainian, and only get redone when the guide changes.

Sky Hook Tower Crane: 112 pieces, 12 steps. One of the easy builds.
Offline: guides you've opened keep working
The site is a PWA. The service worker uses a different strategy per kind of request:
| Request | Strategy |
|---|---|
| Pages | network first; the saved copy if offline or after 4 s with no answer |
| A build's data | network first, saved copy offline: a guide opened once works offline |
/app.js?v=<deploy> | cache first (that address never changes) |
| three.js, fonts | cache first, but only CORS responses (opaque ones can cost ~7 MB of quota each) |
| New designs, chat | network only |
If you open a page that isn't saved, the offline page lists the guides that are, newest first, titled from their cached pages.
The bug that taught me to version everything
One morning a fan build wouldn't open on my phone. The page was new, but the phone still had yesterday's build.js cached (Cloudflare's browser cache keeps it for hours), and yesterday's script didn't know the new /builds/<name> addresses.
Now every script and stylesheet is linked as /<file>?v=<deploy id>, the deploy id taken from the commit SHA. The service worker is served from an API route with the same id baked in, so every deploy changes the worker, browsers install the new one, and it deletes the old deploy's caches. Pages themselves are never served stale.
Pick any guide, press Print or save as PDF, and see how it comes out: trucks, robots, cars or the full list of LEGO build ideas. Everything is free at misterblocks.com.
Unofficial fan builds. LEGO® is a trademark of the LEGO Group, which does not sponsor or endorse this site.




