Live product

BrickDB

bricks.party

Shipped Data pipelineStatic search
BrickDB screenshot

LEGO publishes every building instruction it has ever printed, and makes almost none of it findable. BrickDB indexes 11,696 official PDFs — 264,709 pages across 7,447 sets, 1980 through 2026 — behind a search box that answers before you finish typing. There is no server. The entire database is one JSON file that gzips to 561 KB, sitting on GitHub Pages next to about 30 KB of application JavaScript.

The hard part was never the search. It was the taxonomy. Rebrickable's records carry a numeric theme_id and no theme name, and only part of the scraped corpus came with a human-readable category. So the build step derives the mapping: it tallies, for every theme ID, the category names used by the sets that do have one, and assigns each unlabelled set the plurality winner — with a dozen hand-added fallbacks for themes like One Piece and Bluey that appear only in Rebrickable's half of the data and never in the labelled half. Result: 1,025 full category paths, nested up to six levels, collapsed into 136 clickable facets, and not one of the 7,447 sets left uncategorized. Filtering uses prefix matching, so "Star Wars" catches Star Wars / Episode 9 without a tree widget.

Underneath the PDF search is a second index most visitors never notice: 7,389 sets ship LEGO Studio .io models, 748 ship LDraw, and 1,198 carry community-reconstructed digital builds — machine-readable geometry, not scans. 2,384 sets have more than one booklet (one has eighteen), and Alternative Build, Co-Build and Localized editions are separate, filterable things. All ten filters live in the URL, so any view is a link. And the whole toolchain was ported to run on an Android phone: esbuild's missing android-arm64 binary symlinked to the Linux one, Rollup's native binding swapped for its WASM build, and Vite driven through Bun's JS API because Termux's bionic-linked Node can't load lightningcss's glibc shared objects.

  • Theme IDs have no names in the source data, so the build step resolves each theme_id by plurality vote over the labelled subset — 0 of 7,447 sets end up uncategorized (scripts/build-db.ts:104-136).
  • 1,025 hierarchical category paths, up to six levels deep, collapsed to 136 top-level facets with prefix matching, so "Star Wars" also returns Star Wars / Episode 9 (build-db.ts:206-214, app.svelte.ts:162-169).
  • 11,696 official LEGO PDFs / 264,709 pages / 7,447 sets — 2,384 sets carry multiple booklets, the deepest has 18, the longest single PDF runs 564 pages.
  • A hidden second dataset: 7,389 sets with LEGO Studio .io models, 1,198 community-reconstructed builds, 748 LDraw, 717 OMR, 441 LXF — all filterable.
  • 7.2 MB of JSON that gzips to 574,469 bytes, served static from GitHub Pages against ~30 KB of app JS — the data outweighs the application 19 to 1.
  • Built on a phone: esbuild symlinked to linux-arm64, Rollup replaced with its WASM build, and Vite driven via its JS API under Bun to dodge Termux's bionic/glibc mismatch (postinstall.sh:1-21, scripts/vite-cli.ts).
  • Ten filters, all in the URL, including a genuine tri-state Co-Build filter; popstate re-parses, so back/forward and shared links behave (app.svelte.ts:87-149).