Turn document ยท 2026-05-19
Upgrade apps/web to Next.js 16.2.6
The web app now builds and passes focused validation on Next.js 16.2.6 with React 19. The change keeps route behavior and synthetic admin proxy behavior intact while refreshing the root and Docker workspace Bun lockfiles.
Summary
Upgraded apps/web from the Next 14 / React 18 stack to Next 16.2.6 and React 19.2.x. The Bun lockfile was refreshed, the Docker workspace lock snapshot was synced, and a React 19 nullable ref type issue exposed by the Next 16 build was fixed.
Changes Made
- Updated
apps/web/package.jsonto requestnext ^16.2.6,react ^19.2.0, andreact-dom ^19.2.0. - Updated React type dependencies to
@types/react ^19.2.7and added@types/react-dom ^19.2.3. - Ran
bun install, which resolved Next to16.2.6and React/React DOM to19.2.6inbun.lock. - Ran
bun run sync:docker-workspacesodeployment/docker/workspace-root/bun.lockmatches the root lock snapshot. - Adjusted the terminal list ref types to accept
HTMLDivElement | null, matching React 19's stricter ref object typing. - Allowed Next 16 to regenerate
apps/web/next-env.d.tswith its updated TypeScript reference comment and generated route type import.
Context
The requested upgrade was intentionally dependency-focused. No routes, backend contracts, environment variable names, or shared package exports were changed. Before editing, the web build and the targeted route tests passed on the previous locked Next 14.2.35 stack.
Important Implementation Details
No broad codemod was run. The only source-code change was a targeted type correction in apps/web/app/terminal.tsx. Next 16's build now runs with Turbopack by default in this project and completed successfully after the ref typing was narrowed to the actual nullable runtime value.
The Docker workspace sync changed the mirrored lockfile, but did not need to rewrite the mirrored package manifest or TypeScript base config.
Relevant Diff Snippets
"next": "^16.2.6",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"@types/react": "^19.2.7",
"@types/react-dom": "^19.2.3"
type ListScrollState = {
listRef: React.RefObject<HTMLDivElement | null>;
listNode: HTMLDivElement | null;
setListRef: (node: HTMLDivElement | null) => void;
};
Expected Impact for End-Users
There should be no intentional user-facing behavior change. The expected visible behavior remains: /, /tape, and /news render the terminal app; /signals, /charts, and /replay redirect to /; synthetic admin API routes keep their gated proxy behavior.
Validation
- Baseline before edits:
bun --cwd=apps/web run buildpassed on Next 14.2.35. - Baseline before edits:
bun test apps/web/app/routes.test.tspassed, 3 tests. - Baseline before edits:
bun test apps/web/app/terminal.test.tspassed, 70 tests. - Baseline before edits:
bun test apps/web/app/api/admin/synthetic/routes.test.tspassed, 4 tests. - After upgrade:
bun --cwd=apps/web run buildpassed on Next 16.2.6. - After upgrade:
bun test apps/web/app/routes.test.tspassed, 3 tests. - After upgrade:
bun test apps/web/app/terminal.test.tspassed, 70 tests. - After upgrade:
bun test apps/web/app/api/admin/synthetic/routes.test.tspassed, 4 tests. - After upgrade:
bun run check:docker-workspacepassed. - Manual smoke:
bun run dev:webserved Next 16.2.6 onlocalhost:3000. - Manual smoke: browser checks confirmed
/,/tape, and/newsrender with titleIslandflow Terminal. - Manual smoke:
/signals,/charts, and/replayreturned307redirects to/. - Manual smoke: synthetic admin status and control routes returned gated
404responses when the internal UI flag was off.
Issues, Limitations, and Mitigations
During dev:web smoke testing, the browser logged a live socket channel validation warning because only the web app was running, not the full backend service stack. Route rendering, redirect behavior, and gated synthetic admin proxy behavior were still verified. A full-stack live feed verification can be done separately with bun run dev if needed.
The upgrade did not include a full monorepo test run because the acceptance bar was intentionally web-focused.
Follow-up Work
- No required follow-up Beads issue was opened for this upgrade.
- Optional: run a full-stack live feed smoke with infra and services running if you want runtime stream confidence beyond the web-focused acceptance checks.
- Optional: run the full monorepo
bun testsuite before a larger release branch merge.