Dark Matter Jumps from Astro 5 to Astro 7
A full dependency-upgrade pass took the site from Astro 5 and a stale, workspace-hoisted install to Astro 7 with its own independent lockfile — and uncovered a silent content-collection regression along the way.
Changelog - 2026-07-06 (#1)
Dark Matter Jumps from Astro 5 to Astro 7
Why Care?
Dark Matter (matter-site) was two majors behind the rest of the Astro Knots fleet. This pass brings it current — Astro 7, the Vercel adapter's v11, and every other dependency at latest — and, in the process, gives the site its own independent pnpm-lock.yaml for the first time instead of quietly riding on the parent workspace's hoisted node_modules.
What's New?
Astro 5.16.4 → 7.0.6
@astrojs/vercel 9.0.2 → 11.0.2
@shikijs/rehype 3.20.0 → 4.3.1
satori 0.18.3 → 0.26.0
three 0.181.2 → 0.185.1
tailwindcss / @tailwindcss/vite patch-bumped to 4.3.2 (safe update pass)
Added
@astrojs/check+typescriptas devDependencies soastro checkcan run at all (it never had a typecheck story before)The site now installs from its own local
pnpm-lock.yamlrather than resolving through astro-knots' root workspace — matching the independent-deploy convention every other site in the fleet already follows
How it Works
The safe patch/minor pass (pnpm update) was a no-op — the site's existing semver ranges already permitted the latest 5.x/9.x/3.x/0.18.x/0.181.x releases, so nothing moved until the major bumps started.
Each major was installed and built in isolation, most-important-first: Astro, then the Vercel adapter, then Shiki/Satori/three. Two real breaks surfaced along the way, both from Astro 7's stricter compiler and Vite 8's new rolldown bundler:
<!-- HTML comment -->inside a JS expression insrc/pages/slides/[...slug].astro— legal-ish under Astro 5's compiler, a hard parse error under Astro 7's. Swapped for a/* JS comment */.An unclosed
<BaseThemeLayout>tag insrc/pages/design-system/needs-modes.astro— the file is marked "NOT IN USE" in its own header comment, so nobody had hit this until the compiler got stricter. Closed the tag.A
MISSING_EXPORTforMONTHS_FULL/MONTHS_SHORTinsrc/lib/dates/convertRawDatesToPreferredFormats.ts— these were only ever exported inside the file'sexport default {...}object, never as named exports, even thoughsrc/lib/dates/index.tsre-exported them by name. Astro 5's bundler tolerated the dangling re-export; Vite 8's rolldown does not. Promoted both toexport const.
Under the Hood: the quiet content-collection regression
After the Vercel adapter bump, the build succeeded but silently dropped both markdown-backed slide decks — getCollection('slides') returned [] with a console warning ("does not exist or is empty") instead of throwing. Digging into Astro 7's content/utils.js: legacy type: 'content' collections (still used by narratives, changelog, and slides in src/content.config.ts) are no longer auto-wired to a loader unless legacy.collectionsBackwardsCompat: true is set in astro.config.mjs. Without it, defineCollection() accepts the config without complaint, astro sync reports no errors, types generate correctly — but the collection is simply never populated at build or request time.
Set the flag to restore prior behavior 1:1. The longer-term fix — migrating all three collections to explicit loader: glob(...) definitions — is left as follow-up work; the compat flag is the documented escape hatch and carries no known downside today.
Separately, src/data/markdownDecks.ts was refactored from a top-level await getCollection('slides') (a singleton side effect at module-import time) to a memoized async loader, called lazily from getStaticPaths() and the slides index page. This wasn't the root cause of the collection-empty bug, but it's a more resilient pattern regardless of content-layer timing quirks in future Astro versions.
astro check findings (not fixed, not new)
Running astro check for the first time ever on this project (it had no typecheck dependency before this pass) surfaced 124 pre-existing errors — missing @types/node for node:path/node:fs/Buffer/process/crypto usage across API routes, plus a handful of unrelated component-prop typing gaps (portfolio/index.astro, design-system/flare/white-cell.astro). None of these trace back to the packages bumped in this pass, and none block pnpm build. Left untouched per scope; flagging here so they don't get mistaken for a regression later.
Build Verification
pnpm build— clean pass after every major bump, and again from a fully freshrm -rf node_modules && pnpm installBoth slide decks (
dark-matter-bio-longevity-fund-ii-deck-draft,longevity-science-market-map) confirmed prerendering correctly post-fix, matching pre-upgrade output exactlyThe one runtime warning in the build log (
NocoDB API error: 403) is a pre-existing external API auth issue unrelated to this dependency work — present in the baseline build before any changes too
Files Touched
package.json— version bump to 0.2.5, all dependency ranges updated,@astrojs/check+typescriptaddedpnpm-lock.yaml— new, site-local (previously absent; the site was resolving through the parent workspace's hoisted store)astro.config.mjs— addedlegacy.collectionsBackwardsCompat: truesrc/pages/slides/[...slug].astro— fixed invalid HTML comment in JS expression; switched to lazy markdown-deck loadingsrc/pages/slides/index.astro— switched to lazy markdown-deck loadingsrc/pages/design-system/needs-modes.astro— closed unclosed<BaseThemeLayout>tagsrc/lib/dates/convertRawDatesToPreferredFormats.ts— promotedMONTHS_FULL/MONTHS_SHORTto named exportssrc/data/markdownDecks.ts— refactored from top-level-await singleton to memoized lazy loader
