Stack modernization: Gatsby → Astro (Vite) + Bun + Biome#50
Open
davidbarna wants to merge 1 commit into
Open
Conversation
Full stack modernization replacing Gatsby 5 with Astro 5: - Framework: Gatsby (webpack/babel) → Astro 5 (Vite) with React 19 islands; content collection points at the src/md wiki subtree in place, URLs (/docs/<slug>, /slides/<slug>) preserved exactly - Runtime: npm (--legacy-peer-deps, lockfileVersion 1) → Bun - Lint/format: Prettier config (unused) → Biome (lint + format) - Slideshows: reveal.js 3.7 → 5.2 as a client-only island; slide markdown rendered to HTML at build time (unified + rehype-raw), Shiki replaces prismjs 1.15 - Docs pages: react-markdown/react-syntax-highlighter → Astro built-in markdown + Shiki (zero client JS) - Navigation: @atlaskit/navigation-next suite (+ SSR mocks) → lightweight Astro sidebar - Styling: emotion v10 + styled-components → Astro scoped styles + Sass (reveal theme still compiled from the reveal.js template) - Removed dead code: firebase v8 auth (unreachable UI), react-intl (zero usages), @reach/router, CRA-era leftovers, stale scripts - Fixed /images/... references to work under the /js-training base path via a remark plugin (previously broken in production) - CI: workflows on oven-sh/setup-bun; deploy publishes dist/; e2e workflow gains a Biome lint step - three.js homepage hero kept as a lazy island (three pinned at 0.70; port to current three.js is follow-up work) All 12 Playwright e2e specs pass unchanged against the new stack. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015wQX6V9ysFXjaHYAdF8fHJ
javiyt
approved these changes
Jul 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Full stack modernization in a single PR: Bun as runtime/package manager, Biome for lint + format, and Vite as the builder via Astro 5 (Gatsby has no Vite support, so the framework is replaced). All 12 Playwright e2e specs pass unchanged against the new stack.
What changed
Toolchain
bun.lockreplaces the lockfileVersion-1package-lock.json; no more--legacy-peer-deps(the @atlaskit packages that forced it are gone).prettierrc);bun run lint/bun run format, wired into CIsrc/mdwiki subtree in place — thewiki:add|pull|pushsubtree scripts are untouchedURLs preserved
/docs/<slug>and/slides/<slug>under the/js-trainingbase path are byte-identical (same camelCase→kebab slugify, same directory-format output), so existing links keep working. Since Astro doesn't auto-prefix links like Gatsby's<Link>, all internal hrefs go through awithBase()helper — and dev/preview also serve under the base path, so a missing prefix fails locally, not just in production.Slideshows: reveal.js 3.7 → 5.2
RevealDeck.tsxReact island renders.reveal > .slides > sectionin-tree and callsnew Reveal(el, config).initialize()/destroy()— replaces the old createPortal/body-DOM/head.min.js hackPrism.highlightDOM walk are goneS), parallax background, and slide numbers all verified workingDocs pages
Astro's built-in markdown + Shiki inside
.markdown-body(github-markdown-css) — replaces react-markdown + react-syntax-highlighter with zero client JS. External links open in new tabs viarehype-external-links(replacing the old global<base target="_blank">, which would have broken sidebar navigation).Navigation
The whole
@atlaskit/*suite (navigation-next, button, icon, logo, theme + SSR mocks + webpack aliases) is replaced by a lightweight Astro sidebar with the same gold branding, section grouping fromconstants.ts, and active-link state.Dead code removed (verified unreachable before deletion)
material-ui, which isn't even in package.json — it could never compile, and nothing live imported it. Its only purpose was gating reveal multiplex "teacher mode" against a dead server.src/index.js/index.html, components importing uninstalledreact-helmet, broken nav components, stale one-off scripts, thesui-monopackage.json blockFixed along the way
Markdown images referenced as
/images/...resolved to the domain root and were broken in production under the/js-trainingprefix; a small remark plugin now prefixes them with the base path at build time.Kept
client:idleisland, still pinned to three 0.70 — porting to current three.js is deliberate follow-up workMarkdownParser.tsslide-splitting logic reused verbatim (e2e slide ids depend on it)CI/CD
oven-sh/setup-bun@v2+bun install --frozen-lockfiledeploy.ymlpublishesdist/via peaceiris (no repo-settings change needed); Gatsby caches, the sharp toolchain, and theNODE_OPTIONSheap bump are gonee2e.ymlgains a Biome lint gateUA-146160304-1) was droppedNumbers
astro preview, verified from a cold buildFollow-up candidates
src/packages/three-backgroundto current three.js (or replace with static art)strictviaastro/tsconfigs/strict+astro checkin CIactions/deploy-pages(requires flipping the repo's Pages source to "GitHub Actions"),@astrojs/sitemap, OG meta🤖 Generated with Claude Code
https://claude.ai/code/session_015wQX6V9ysFXjaHYAdF8fHJ
Generated by Claude Code