chore(deps): upgrade Next.js 15 → 16 + React 18 → 19 - #114
Merged
Conversation
Framework major upgrade, stacked on #111 (Next 14 → 15). Dependencies: - next 15.5.21 → 16.2.12 - react / react-dom 18 → 19.2.8, @types/react(-dom) → 19 - eslint 8 → 9 (flat config), eslint-config-next → 16, @typescript-eslint 6 → 8 (also clears the lingering ts-eslint Dependabot alert) Config migrations required by Next 16: - `next lint` removed → lint scripts use `eslint .`; migrated .eslintrc.json to eslint.config.mjs (flat) composing eslint-config-next 16's native flat configs (FlatCompat crashes on the react plugin's circular flat object) - typedRoutes graduated from `experimental` to a stable top-level option - tsconfig target es5 → ES2017 (Next 16 drops es5; noEmit, so type-check only) React 19 type-tightening fixes (behaviour unchanged): - ImgHTMLAttributes['src'] widened to string | Blob → narrow before string ops (MDXComponents, ServerMDXContent) - ReactElement['props'] is now unknown → annotate read shape (guides pre block) - useRef<T>(null) returns RefObject<T | null> → widen ChatMessageList prop Deferred (out of scope for a framework upgrade, tracked as follow-up): eslint-plugin-react-hooks v6 (bundled with Next 16) adds React-Compiler-era rules (set-state-in-effect, error-boundaries, immutability) that flag 30 pre-existing intentional patterns; disabled here. no-unused-vars caughtErrors pinned to 'none' to preserve the pre-upgrade contract (v8 flipped the default). Verified: tsc --noEmit, next build (Turbopack, all pages), eslint ., jest 227 pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Jul 26, 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.
Framework major upgrade. Stacks on #111 (Next 14 → 15) — base is
deps/next-15so this diff shows only the 15 → 16 delta and will auto-retarget tomainwhen #111 merges. Merge order: #111 → this. (Security PRs #112/#113 are independent overrides that combine at merge.)What changed
Dependencies
next15.5.21 → 16.2.12react/react-dom18 → 19.2.8,@types/react(-dom)→ 19eslint8 → 9 (flat config),eslint-config-next→ 16,@typescript-eslint6 → 8 — also clears the lingering ts-eslint Dependabot alertConfig migrations Next 16 requires
next lintwas removed → lint scripts now runeslint .;.eslintrc.jsonmigrated toeslint.config.mjs(flat config) composing eslint-config-next 16's native flat configs. (FlatCompat crashes with a circular-JSON error on the react plugin — same class as the sbb-lost-found lint crash.)typedRoutesgraduated fromexperimental→ stable top-level optiontargetes5 → ES2017 (Next 16 drops es5;noEmit, so this only affects type-checking, not SWC output)next-env.d.tsregenerated to Next 16'simport-based formReact 19 type-tightening (runtime behaviour unchanged)
ImgHTMLAttributes['src']widened tostring | Blob→ narrow before string ops (MDXComponents,ServerMDXContent)ReactElement['props']is nowunknown→ annotate the read shape (guidespreblock)useRef<T>(null)returnsRefObject<T | null>→ widen theChatMessageListpropeslint-plugin-react-hooksv6 (bundled with Next 16) adds React-Compiler-era rules —set-state-in-effect(13),error-boundaries(12),immutability(5) — that flag 30 pre-existing intentional patterns (localStorage hydration, load-on-mount effects). Adopting them is a dedicated 30-site refactor with real behaviour risk, so they're disabled here and left as a tracked follow-up.rules-of-hooksandexhaustive-depsstay enabled.no-unused-varscaughtErrorspinned to'none'to preserve the pre-upgrade contract (v8 flipped the default to'all', which would newly flag every unusedcatchbinding).Verification
tsc --noEmit— cleannext build(Turbopack, all pages)eslint .(flat config) — 0 problemsjest— 227 passed, 2 skipped🤖 Generated with Claude Code