Skip to content

v2.61.0

Latest

Choose a tag to compare

@github-actions github-actions released this 21 Jul 10:53
Immutable release. Only release title and notes can be modified.
a5a9f5f

Every dependency in the workspace is now on its latest release, including pnpm 11 and TypeScript 7. One package is deliberately held back — graphql — for a reason spelled out below. Split into one commit per logical upgrade so each can be reviewed or reverted on its own.

Minor / patch bumps

Next 16.1.4 → 16.2.10, React + React DOM 19.2.3 → 19.2.7, Jest 30.2 → 30.4, Turbo 2.8.3 → 2.10.5, pg 8.17.2 → 8.22.0, sequelize 6.37.7 → 6.37.8, valibot 1.2.0 → 1.4.2, tsx 4.21 → 4.23.1, wretch 3.0.6 → 3.0.9, plus Contentful / Font Awesome / @types/* patch bumps. chalk is now pinned exactly to match saveExact.

Biome 2.3.12 → 2.5.5

biome migrate moved noImportCycles out of nursery into suspicious and renamed recommendedpreset. 2.5 also adds two new rules under the react: all domain, both turned off:

  • performance/noJsxPropsBind — asks for useCallback, which contradicts this repo's React Compiler rule (27 findings).
  • suspicious/noLeakedRender — its 3 findings are ternaries whose branches are typed string/ReactElement, so TS already rules out the bug class.

Biome output is back to the same 2 pre-existing suppressions/unused warnings as main.

Drop-in majors

@testing-library/jest-dom 6 → 7, @types/node 25 → 26, sharp 0.34 → 0.35, ora 8 → 9, @vercel/analytics 1 → 2, @vercel/speed-insights 1 → 2, vercel CLI 50 → 56. jest-dom 7 promotes @testing-library/dom to a required peer, so @dg/testing declares it directly instead of leaning on autoInstallPeers.

lucide-react 0.563 → 1.25

v1 removes all brand icons for trademark reasons, so Github/Instagram no longer exist. packages/ui/dependent/Link.tsx renders those two marks through FaIcon + @fortawesome/free-brands-svg-icons, matching how linkedin/spotify/strava already worked — no new dependency.

MUI 7.3.7 → 9.2.0

Material UI skipped v8, so this is a single migration. v9 removes system props from Box, Stack, Typography, Link, Grid and DialogContentText; without migrating, those props silently drop their CSS and leak to the DOM. Ran the official codemod:

npx @mui/codemod@9.1.0 v9.0.0/system-props apps packages

That fixed all 15 type errors across 9 files. Hand-tidied afterwards: folded textAlign into the existing messageSx constant in ErrorLayout.tsx rather than keeping the codemod's defensive sx array, and restored blank lines it stripped. Emotion stays the style engine and all 448 generated CSS variables are byte-identical. AppRouterCacheProvider now imports from @mui/material-nextjs/v16-appRouter.

@vercel/og 0.8.6 → 0.11.1

Brings satori 0.16 → 0.25, which fixes the root background not painting across the padding box. The social image no longer has black gutters:

Open Graph image before and after the @vercel/og upgrade

TypeScript 5.9.3 → 7.0.2

Two things stand in the way of TS 7 and both have supported answers.

No compiler API. TS 7's export map only exposes version.cjs, and Next needs the API for its build-time check. TypeScript ships a bridge for exactly this, so the catalog uses the documented alias pair:

'@typescript/native': npm:typescript@7.0.2
typescript: npm:@typescript/typescript6@6.0.2

tsc is now 7.0.2, tsc6 is 6.0.3, and require('typescript') returns the 6.0 API. Verified Next's check is real and not vacuous by planting a deliberate string-to-number error: next build failed with Type error: Type 'string' is not assignable to type 'number', and tsc and tsc6 both flagged the same line.

types now defaults to []. Every workspace declares the ambient @types packages it uses (["node"] in base.json, ["jest", "node"] where tests are type-checked). That surfaced two workspaces relying on a transitive @types/node; both now declare it. Worth noting this was not a pnpm symlink problem — a real node_modules/@types/node directory fails the same way, and it's documented as intentional.

The payoff, measured on identical source with both compilers installed side by side:

Typecheck benchmark comparing TypeScript 6.0.3 and 7.0.2

Also drops the typescript.tsdk pin from .vscode/settings.json, since the bridge ships no tsserver. One trade-off to know about: the next TypeScript plugin is a language-service plugin, and those only load under a TS 6 language server, so run VS Code's "Disable TypeScript 7 Language Server" if you want it back in-editor. CLI and CI are unaffected.

pnpm 10.28.2 → 11.15.1

Config migration, since v11 moves and renames a lot:

  • .npmrc is auth/registry only now, so save-exact, auto-install-peers and engine-strict move into pnpm-workspace.yaml as camelCase keys, and .npmrc is gone. turbo.json globalDependencies tracks pnpm-workspace.yaml instead.
  • onlyBuiltDependencies is ignored and strictDepBuilds now defaults on, so the allowlist becomes an allowBuilds map. pnpm's own detection pruned the stale @biomejs/biome and @vercel/speed-insights entries — both dropped their install scripts a while ago.
  • verifyDepsBeforeRun defaults to install, re-verifying dependencies on every pnpm run. Turbo already gates tasks behind one install, and turning it off cut a 10-task check:types run from 4.68s to 3.50s.
  • confirmModulesPurge: false so the first install on the v11 store doesn't hard-fail with ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY.

minimumReleaseAge now quarantines releases younger than a day. Kept that default on — it's a good supply-chain default. pnpm records the versions we deliberately pinned fresh in minimumReleaseAgeExclude, so the policy still covers everything else. One thing to know: pnpm appends to that list but never prunes it, so entries for packages that have since moved on can be deleted by hand.

Also verified pnpm exec still works through Turbo — turbo migrate:status reports all four migrations up against a real Postgres.

Held back, with a reason

Package Current Latest Why
graphql 16.14.2 17.0.2 graphql-request@7.4.0 (still latest) declares graphql: "14 - 16".

I did test 17 rather than assume. With a peerDependencyRules.allowedVersions override it works: pnpm peers check is clean, typecheck and all 268 tests pass, all five Contentful queries render real content through graphql-request, and the error path is fine too — I injected a GraphQL error response and it surfaced with message, path and extensions intact, no GraphQLError constructor breakage.

So this is a supportedness call, not a breakage one. graphql-request is a production dependency that fetches every piece of site content, graphql itself is only a devDependency used by one schema-generation script, and the sole gain would be one fewer row in pnpm outdated. Forcing a production content path outside its library's declared peer range for that isn't a good trade, so 16.14.2 — the newest release inside the supported range — is what shipped. Happy to flip it if you'd rather.

Verification

turbo check:ci, turbo check:types and turbo test all pass — 27/27 tasks, 39 suites, 268 tests. Tests ran against a real local Postgres so the pg 8.22 / sequelize 6.37.8 bumps are exercised, and sharp 0.35.3 / libvips 8.18.3 runs for real in the image tests. next build --turbopack is fully green locally: compiled, Finished TypeScript, all 8 static pages generated.

CI confirms the toolchain is genuinely in use, not silently falling back:

Run pnpm/action-setup@v4   + pnpm 11.15.1
Run pnpm install           + @typescript/native <- typescript 7.0.2
Run pnpm install           + typescript <- @typescript/typescript6 6.0.2
Run pnpm install           Done in 7.9s using pnpm v11.15.1
check:types                $ tsc --noEmit

The Vercel check is green too, which means a real next build with real credentials prerendered every page on pnpm 11 + TS 7.

For the UI-facing upgrades I ran main and this branch side by side on two dev servers, both fed identical fixtures shaped like the live site (real project entries, real public images.ctfassets.net URLs so next/image and the sharp gradient extraction run for real).

Homepage — same layout, same grid, same real images:

Homepage rendered on main versus this branch

Measured over CDP rather than eyeballed. Document height is 1972px on both. Every card has an identical width, height and x; the only delta is a uniform +0.58px on y from the slightly taller intro text. Requesting the same /_next/image URL from both servers returns byte-identical output. A 12x-amplified pixel diff shows the changes are confined to text, the two swapped brand marks, and sub-pixel edges from that shift:

Amplified pixel diff of the homepage between main and this branch

Re-measured after pnpm 11 and TS 7 landed: all ten cards identical in x, y, width and height, and docHeight unchanged — as expected, since both are build-time only.

Dev console — every file the MUI codemod touched. Measured the vertical gaps between stacked children in all four cards: 16px on both versions, identical:

Dev console rendered on main versus this branch

Footer brand marks — the one intentional visual change. Font Awesome's GitHub mark is filled where lucide's was outlined, which matches its LinkedIn / Spotify / Strava neighbours better:

Footer brand icons before and after moving GitHub and Instagram to Font Awesome

Interaction smoke test — theme switch, footer tooltips, dev console render, Dry run checkbox:

upgraded_deps_theme_toggle_footer_tooltips_dev_console_checkbox.mp4

Also confirmed by driving Chrome over CDP against both versions:

  • Browser console is identical — 1 pre-existing Missing token log from absent OAuth credentials, zero hydration mismatches on either.
  • The Dry run checkbox toggles false → true → false with the icon swapping CheckBoxOutlineBlankIconCheckBoxIcon, same on MUI 7 and 9:

Dry run checkbox unchecked and checked on MUI 7 and MUI 9

  • Footer svghrefaria-label → tooltip mapping audited element by element; every row lines up (fa-githubgithub.com/dgattey → "GitHub", fa-instagraminstagram.com/dylangattey → "Instagram", and so on).

One thing worth a look

MUI 9 ships a fix for mui/material-ui#40255: responsiveFontSizes now preserves the theme's designed font size at the largest breakpoint instead of letting grid alignment snap it. At min-width:992px the generated scale changes:

variant designed v7 v9
h1 34px 2.1422rem 2.125rem
h2 29.75px 1.875rem 1.8594rem
h3 24.75px 1.4996rem 1.5469rem
h5 16.5px 1.1244rem 1.0313rem
body1 17px 1rem 1.0625rem
body2 17px 1.049rem 1.0625rem

v9 lands exactly on designed / 16 rem, so packages/ui/theme/typography.ts is finally rendering the numbers it declares. In practice body copy grows ~1px and h5 shrinks ~1px on wide screens. Nothing needs changing, but those values are worth a glance now that they're honoured literally.

Unrelated: the screenshot workflow

Screenshots / 📸 Screenshots reports success but its "after" images are just Vercel's Log in to Vercel page, so the deployment-protection bypass isn't reaching agent-browser. This predates the PR — screenshots/pr-541 produced 14-byte files, and screenshots/pr-538 was the last run to capture the real app. Untouched here, but it means the CI visual diff on this PR carries no signal.

Also fixed in passing

@dg/tsconfig's files list named a react.json that doesn't exist and omitted the library.json that ten workspaces actually extend.