Skip to content

Stop each site shipping the other one, and split the machines out - #18

Merged
hotpixelgroup merged 1 commit into
mainfrom
bundle-size
Aug 27, 2026
Merged

hotpixelgroup merged 1 commit into
mainfrom
bundle-size

Conversation

@hotpixelgroup

Copy link
Copy Markdown
Owner

The bundle had grown to just over a megabyte, and worse than the size was what was in it: every visitor to either site downloaded the whole of the other curriculum, runners included, because the filtering happened at runtime. That was a cost of the one-build-two-front-doors design I never priced when I proposed it.

Two changes

Per-site registries. The app resolves @site-quests to one of them through a Vite alias, so the other curriculum is never in the graph. Reaching it through the package index would pull it straight back, so the app and packages/ui now import from a registry-free entry point that says so in a comment.

Lazy machines. All 24 runners and 22 figures load on demand behind Suspense rather than shipping with the app. 57 chunks instead of 1.

bitcoin4plebs    1,007 kB → 678 kB   (gzip 330 → 223)
lightning4plebs  1,007 kB → 534 kB   (gzip 330 → 171)

Verified by content, not just by size: Bitcoin quest prose is absent from the Lightning bundle and vice versa. The bundles are now different sizes, which they could not be before.

A live bug this surfaced

The glossary popover in packages/ui built a number→slug map across both curricula. Quest numbers restart per site, so Lightning #1–7 silently overwrote Bitcoin #1–7. A term on the Bitcoin site citing Quest #3 was linking to the Lightning slug, which isn't routable there: a dead internal link.

I introduced that with the site split and hadn't noticed. It now resolves through the slug index using the entry's own site, linking internally when that matches and across when it doesn't. Verified in-browser: a Lightning term citing Bitcoin #16 renders an external link to a-thousand-coffees.

The slug index is a few hundred bytes of number→slug, so a site can deep-link into its sibling without importing the sibling's data. A test fails if it drifts from the real registries.

147 tests green; lint, build, typecheck clean. Runner and figure loading verified in-browser.

🤖 Generated with Claude Code

The bundle had grown to just over a megabyte, and worse than the size was
what was in it: every visitor to either site downloaded the whole of the
other curriculum, runners included, because the filtering happened at
runtime. That was a cost of the one-build-two-front-doors design that I
never priced when I proposed it.

Two changes. The registries are now per site, and the app resolves
'@site-quests' to one of them through a Vite alias, so the other
curriculum is never in the graph. Reaching it through the package index
would have pulled it back, so the app and the ui package now import from
a registry-free entry point that says so in a comment. Separately, all 24
runners and 22 figures load on demand rather than shipping with the app,
behind Suspense.

  bitcoin4plebs    1,007 kB -> 678 kB   (gzip 330 -> 223)
  lightning4plebs  1,007 kB -> 534 kB   (gzip 330 -> 171)

Doing this surfaced a live bug I had introduced with the site split. The
glossary popover built a number-to-slug map across both curricula, and
quest numbers restart per site, so Lightning #1 to #7 silently overwrote
Bitcoin #1 to #7. A term on the Bitcoin site citing Quest #3 was linking
to the Lightning slug, which is not routable there. It now resolves
through the slug index with the entry's own site, links internally when
that matches and across when it does not.

That index is a few hundred bytes of number-to-slug so a site can deep
link into its sibling without importing the sibling's data. A test fails
if it drifts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@hotpixelgroup
hotpixelgroup merged commit 14663a3 into main Aug 27, 2026
1 check passed
@hotpixelgroup
hotpixelgroup deleted the bundle-size branch August 27, 2026 07:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant