Skip to content

MAINT: Update npm dependencies - #326

Merged
VeckoTheGecko merged 19 commits into
mainfrom
update-npm-deps
Oct 28, 2026
Merged

VeckoTheGecko merged 19 commits into
mainfrom
update-npm-deps

Conversation

@VeckoTheGecko

@VeckoTheGecko VeckoTheGecko commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

I have gone through all the code here, and think that it looks good. I have also done inspections of the website.

This change sticks close to the original site design (I did try a version with the v4 Chakra UI defaults, but I think this version looks better)


Note

This PR (code changes and this description) was generated by an LLM (Claude Opus 5.5). Please review with that in mind, especially the Chakra UI v3 migration.

Updates every npm dependency to its latest version, except two that are held back (see below), and migrates the code to match. Each upgrade is its own commit, so the PR is easiest to review commit by commit.

Version bumps

Major

Package From To
next, @next/mdx 14 16.4.3
eslint-config-next 15.2.4 16.4.3
react, react-dom 18.3 19.3.1
@types/react 18.3 19.3.0
@chakra-ui/react 2.9 3.37.0
eslint 9 10.13.0
typescript >=5.7.3 ^6.0.3
date-fns 3 4.4.0
feed 4.2 6.0.0
glob 11 13.0.6
katex 0.16 0.19.1
framer-motion 11 14.7.0
next-mdx-remote 5 6.0.0
react-ga4 2.1 3.0.1
react-syntax-highlighter 15 16.1.2
apexcharts / react-apexcharts 4 / 1.4 8.5.0 / 2.1.1
isomorphic-dompurify 2.16 ~3.19.0

Minor/patch

@emotion/react, @fontsource-variable/inter, @mdx-js/loader, @mdx-js/react, react-icons, swr, playwright, webpack.

Added / removed

  • Added: next-themes (used by Chakra v3 for colour mode), plus an npm overrides entry pinning katex (see below).
  • Removed: @chakra-ui/icons, @chakra-ui/next-js, @chakra-ui/system, @emotion/styled. Chakra v3 no longer uses them, or they were unused.

Code and config changes

Next.js 16

  • next.config.mjs: images.domains → images.remotePatterns. rehype-slug is now referenced by package name, because Turbopack (now the default bundler) requires serializable loader options.
  • next lint was removed, so the lint script is now eslint ., and .eslintrc is replaced by a flat eslint.config.mjs.
  • Next regenerated tsconfig.json and next-env.d.ts.
  • Deleted src/pages/waddendrifters.html.tsx. Under Turbopack its output collided with the exported waddendrifters.html, and the build failed (EISDIR). The static export still emits waddendrifters.html from src/pages/waddendrifters.tsx (same redirect to /blog/waddendrifters), so /waddendrifters.html keeps working on GitHub Pages.

Chakra UI v3

  • Started from the official @chakra-ui/codemod, then finished every file by hand.
  • The theme is rebuilt with createSystem. It carries over the v2 container sizes and padding, heading scale, inline link style, dark background and border colours.
  • The official provider, colour-mode and tooltip snippets are added under src/components/ui/.
  • Colour-dependent styling uses _dark CSS conditions, so the static HTML is correct before React hydrates.
  • Accordion, Alert, Avatar (via a new AuthorAvatar helper), Card, Collapsible, Separator and HoverCard use the v3 component structure. Renamed props are updated.
  • Markdown posts lost their list bullets/numbers under the v3 CSS reset, so list styles are now set explicitly.
  • Removed the unused SocialButton in the footer.
  • The site looks close to before but not identical: buttons, avatars and some greys differ a little, and avatar fallbacks are now plain grey circles.

feed v6

  • Item ids must now be URLs. With bare slugs it threw Invalid URL, so atom.xml was silently not being written while the build still reported success. Items now use the post URL as their id.
  • generateRssFeed is now awaited, so a feed error fails the build instead of being swallowed.
  • ⚠️ Existing posts get new GUIDs, so feed readers may show them as new once.

next-mdx-remote v6

  • v6 strips JS expressions by default, which removed a style={{...}} in the Parcels v4 post. Set blockJS: false and kept blockDangerousJS on.

katex 0.19

  • KaTeX class names changed in 0.18. An npm overrides entry ("katex": "$katex") makes rehype-katex render with the same KaTeX version as the imported stylesheet.

isomorphic-dompurify

  • Switched to the named sanitize export.

TypeScript 6

  • The tsconfig.json target moves from ES5 (now a hard error) to ES2017.

Lint fixes

Linting was already broken on main: next lint crashed on ESLint 9. Now that it runs, it found two errors, both fixed:

  • hooks called inside a .map() in desktop-nav.js;
  • an unescaped apostrophe in utrechtteam.js.

No code changes needed

React 19, date-fns 4, glob 13, react-ga4 3, react-syntax-highlighter 16, framer-motion 14.

Held back

  • isomorphic-dompurify stays at ~3.19.0, not 4.x. Versions 3.20 and up need Node ≥22.22.2 or ≥24.15, and the deploy workflow builds on Node 20, so they crash the build there. It can be bumped once CI moves to a newer Node.
  • typescript stays at 6.x, not 7. typescript-eslint (via eslint-config-next) refuses to load with TS 7 and only supports versions below 6.1.

Known caveats

  • npm prints peer-dependency warnings for ESLint 10, because eslint-plugin-react, -import and -jsx-a11y still declare support only up to ESLint 9. npm ci succeeds and the rules still run.
  • apexcharts, react-apexcharts and d3 aren't imported anywhere and could be removed in a follow-up.

Testing

  • npm run build passes on Node 24, and on Node 20 after every step.
  • npm run lint is clean.
  • npm ci works from the lockfile, and npm audit reports 0 vulnerabilities.
  • A headless-browser smoke test passed at each step: every page loads with no console errors on desktop and mobile, the colour-mode toggle, mobile nav and papers accordion work, and the dev-only /cards/[id] page renders.

🤖 Generated with Claude Code

Bump all dependencies to the latest release within their current
major version (Next.js 14.2.35, Chakra UI 2.10.10, ESLint 9.39.5,
TypeScript 5.9.3, Playwright 1.64.1, webpack 5.112.2, etc.) and pin
TypeScript to ^5 instead of the open-ended >=5.7.3 range.
date-fns v4 adds first-class time zone support; the only breaking
changes concern TypeScript types and internal module layout. The
formatDistanceToNow API used in src/lib/date-formatting.js is
unchanged, and date-fns-tz 3.2 supports date-fns ^4.
feed v6 validates item ids as URLs when rendering Atom (Atom <id> must
be an IRI), so the bare post slug threw 'Invalid URL' and atom.xml was
silently not written. Use the post URL as the item id, and await
generateRssFeed in getStaticProps so feed errors fail the build
instead of being swallowed as an unhandled rejection.
The only breaking changes in glob 12/13 affect the CLI (unsafe --shell
removed, CLI moved to glob-bin); the glob.sync API used in
src/lib/posts.js is unchanged.
v3 stops writing to global.DOMPurify and adds named exports; switch
src/lib/sanitize-html.js to the named 'sanitize' export.

Pinned to ~3.19.0 rather than v4: 3.20+ / 4.x pull in jsdom 30, whose
undici dependency crashes on Node 20 ('Cannot read properties of
undefined (reading bind)') and requires Node ^22.22.2 || ^24.15.0.
The deploy workflow still builds on Node 20, so v4 is held back until
CI moves to a newer Node.
KaTeX 0.18 prefixes all internal CSS classes, so the stylesheet
imported from katex/dist must match the KaTeX version that renders the
math. rehype-katex 7 still declares katex ^0.16, so add an npm
override forcing it (and micromark-extension-math) onto the top-level
katex version. Its renderToString API is unchanged.

Other breaking changes (strict-mode reporting of missing metrics in
0.19, internal __defineFunction API in 0.17) do not affect this site.
v3 is a rewrite in TypeScript published as ESM-only; the default
export and the initialize()/send() API used in layout.js are
unchanged.
v16 upgrades its refractor dependency to v5 (security fixes). The
Prism component and the dist/cjs/styles/prism import path used in
src/components/mdx/code.js are unchanged; verified Python code still
tokenises and renders with the nord theme.
react-apexcharts 2 requires apexcharts >=5.10.1, so they are upgraded
together. Neither package is currently imported anywhere in the site,
so no code changes are needed.
v6 adds blockJS/blockDangerousJS serialize options, both defaulting to
true, which strips every JS expression from MDX. That silently dropped
the style={{...}} attribute in the parcels-v4 post. Posts are authored
in this repository, so pass blockJS: false to keep expressions while
leaving blockDangerousJS enabled.
Breaking changes since v11 (gesture callbacks receiving the target
element in v12, removal of the optional @emotion/is-prop-valid
dependency in v13, removal of internal compatibility APIs in v14) do
not affect the motion.div used on the blog index or Chakra UI v2's
internal transitions. Smoke-tested all pages, colour-mode toggle and
the mobile navigation in a headless browser.
Upgrade next, @next/mdx and eslint-config-next to 16.4.3 and migrate:

- next lint was removed in Next.js 16: replace .eslintrc with a flat
  eslint.config.mjs based on eslint-config-next/core-web-vitals and
  run the ESLint CLI directly. (next lint had already been broken
  with ESLint 9.) Fix the two errors it now reports: hooks called
  inside a map callback in desktop-nav.js, and an unescaped
  apostrophe in utrechtteam.js.
- Turbopack is now the default bundler and only accepts serializable
  loader options, so reference rehype-slug by name in the @next/mdx
  config.
- images.domains is deprecated; use images.remotePatterns.
- Turbopack emits a per-page directory under .next/server/pages, so
  the waddendrifters.html page's chunk directory collided with the
  exported waddendrifters.html of the /waddendrifters page (EISDIR).
  Remove the duplicate waddendrifters.html page: on GitHub Pages a
  request for /waddendrifters.html is already served by the
  waddendrifters.html redirect page exported from /waddendrifters.
- Accept the tsconfig.json and next-env.d.ts changes written by
  next build (jsx: react-jsx, generated route type imports).
Upgrade react, react-dom and @types/react to 19. Next.js 16 deprecates
React 18 support for the Pages Router. The site does not use any of
the APIs removed in React 19 (propTypes/defaultProps on function
components, string refs, legacy context, ReactDOM.render, the global
JSX namespace); forwardRef in mdx/link.js is still supported.
Chakra UI v2 runs on React 19 without console errors (checked with a
headless-browser smoke test of every page).
ESLint 10 drops eslintrc support entirely (already migrated to flat
config with the Next.js 16 upgrade) and no longer honours
/* eslint-env */ comments (none in this repo). eslint-config-next
16.4+ supports ESLint 10.

Note: eslint-plugin-react, eslint-plugin-import and
eslint-plugin-jsx-a11y (pulled in by eslint-config-next) have not yet
widened their eslint peer range beyond ^9, so npm prints ERESOLVE
peer warnings. npm ci still succeeds and the plugins' rules run
correctly under ESLint 10.
TypeScript 6 deprecates target ES5 (a hard error in next build's type
check), so raise tsconfig's target to ES2017, the Next.js default.
The target only affects type checking here since Next.js compiles
with SWC.

TypeScript 7 (7.0.2) is held back: its package no longer exposes the
JavaScript compiler API, and typescript-eslint (used by
eslint-config-next) refuses to load with it ('typescript-eslint does
not support TS 7.0'; peer range is <6.1.0).
Chakra UI v3 is a rewrite with a new theming system and compound
component APIs. Migration (codemod-assisted via @chakra-ui/codemod,
then reviewed and finished by hand):

Packages
- @chakra-ui/react 2 -> 3. Remove @chakra-ui/icons, @chakra-ui/next-js
  and @chakra-ui/system (no v3 equivalents; next-js was unused) and
  @emotion/styled (no longer needed). Icons now come from react-icons
  (Lucide set). Add next-themes for colour mode.

Theme and providers
- Replace extendTheme with createSystem/defineConfig in src/theme.js.
  To keep the site looking as before, restore v2's container sizes
  (container.lg etc.), responsive heading scale, inline links that
  inherit text colour, 1rem container padding, dark background
  (gray.800) and border colours.
- Add the official v3 snippets in src/components/ui (provider,
  color-mode, tooltip). _app uses <Provider>; ColorModeScript is
  replaced by next-themes (suppressHydrationWarning on <Html>).

Components
- useColorModeValue/useColorMode-based styling replaced by _dark
  conditions so the static export renders correctly before hydration;
  ColorModeImage renders both images and toggles them with CSS; the
  colour-mode toggle is wrapped in ClientOnly.
- Compound components: Accordion, Alert, Avatar (new AuthorAvatar
  helper), Card, Collapsible, Separator (was Divider), StackSeparator,
  Tooltip snippet; hover Popover -> HoverCard in the desktop nav.
- Prop renames: spacing -> gap, colorScheme -> colorPalette,
  noOfLines -> lineClamp, isOpen -> open, defaultIsOpen -> defaultOpen,
  icon/leftIcon -> children, as={Link} -> asChild, isExternal removed
  (custom Link already sets target/rel for external URLs),
  useClipboard({ value }) returns { copied, copy }.
- MDX lists get explicit list-style types (v3's preflight removes them).
- Drop the unused SocialButton from the footer.

@erikvansebille erikvansebille left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good indeed - happy to be merged

@VeckoTheGecko
VeckoTheGecko merged commit aacfbc4 into main Oct 28, 2026
5 checks passed
@VeckoTheGecko
VeckoTheGecko deleted the update-npm-deps branch October 28, 2026 14:18
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.

2 participants