Skip to content

Stack modernization: Gatsby → Astro (Vite) + Bun + Biome#50

Open
davidbarna wants to merge 1 commit into
masterfrom
claude/stack-modernization-plan-sg2lhc
Open

Stack modernization: Gatsby → Astro (Vite) + Bun + Biome#50
davidbarna wants to merge 1 commit into
masterfrom
claude/stack-modernization-plan-sg2lhc

Conversation

@davidbarna

Copy link
Copy Markdown
Collaborator

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

  • npm → Bun: bun.lock replaces the lockfileVersion-1 package-lock.json; no more --legacy-peer-deps (the @atlaskit packages that forced it are gone)
  • Biome (net-new linting + formatting, replaces the unused .prettierrc); bun run lint / bun run format, wired into CI
  • Gatsby 5 → Astro 5 (Vite): content collection globs the src/md wiki subtree in place — the wiki:add|pull|push subtree scripts are untouched

URLs preserved

/docs/<slug> and /slides/<slug> under the /js-training base 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 a withBase() 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.tsx React island renders .reveal > .slides > section in-tree and calls new Reveal(el, config).initialize() / destroy() — replaces the old createPortal/body-DOM/head.min.js hack
  • Slide markdown is rendered to HTML at build time (unified: remark-gfm + rehype-raw, the same chain react-markdown used) with Shiki highlighting — prismjs 1.15 and the manual Prism.highlight DOM walk are gone
  • Custom theme still compiles from the reveal.js theme template (shipped in the reveal 5 npm package); exercise/solution/important slide variants, speaker notes (S), parallax background, and slide numbers all verified working
  • Dead multiplex/socket.io/now.sh CDN config removed (the multiplex plugin was removed in reveal 4.x and its server is long dead)

Docs 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 via rehype-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 from constants.ts, and active-link state.

Dead code removed (verified unreachable before deletion)

  • firebase v8 auth: the sign-in UI imports 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.
  • react-intl (zero usages), @reach/router, CRA-era src/index.js/index.html, components importing uninstalled react-helmet, broken nav components, stale one-off scripts, the sui-mono package.json block
  • emotion v10 + styled-components v6 → Astro scoped styles + Sass (one styling system)

Fixed along the way

Markdown images referenced as /images/... resolved to the domain root and were broken in production under the /js-training prefix; a small remark plugin now prefixes them with the base path at build time.

Kept

  • three.js homepage hero (decorative cube-logo animation) as a lazy client:idle island, still pinned to three 0.70 — porting to current three.js is deliberate follow-up work
  • MarkdownParser.ts slide-splitting logic reused verbatim (e2e slide ids depend on it)
  • Playwright e2e suite unchanged except baseURL/webServer config

CI/CD

  • Both workflows on oven-sh/setup-bun@v2 + bun install --frozen-lockfile
  • deploy.yml publishes dist/ via peaceiris (no repo-settings change needed); Gatsby caches, the sharp toolchain, and the NODE_OPTIONS heap bump are gone
  • e2e.yml gains a Biome lint gate
  • The dead Universal Analytics tag (UA-146160304-1) was dropped

Numbers

  • 141 files changed, +2,141 / −23,369
  • 27 runtime/build dependencies removed; build produces 44 static pages in ~18s
  • 12/12 e2e specs green (home, docs, slideshow) against astro preview, verified from a cold build

Follow-up candidates

  • Port src/packages/three-background to current three.js (or replace with static art)
  • TypeScript strict via astro/tsconfigs/strict + astro check in CI
  • Optional: switch deploy to actions/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

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
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.

3 participants