Skip to content

chore: modernize stack - #12

Merged
feedsbrain merged 11 commits into
mainfrom
chore/modernize
Sep 9, 2026
Merged

feedsbrain merged 11 commits into
mainfrom
chore/modernize

Conversation

@feedsbrain

Copy link
Copy Markdown
Contributor

Modernizing stack and ui

feedsbrain and others added 11 commits September 8, 2026 23:51
MIGRATION.md §0. Bump `.tool-versions` to `nodejs 24.20.0` and drop the
`python 3.9.5` line (only the old native canvas / tfjs-node toolchain needed
it). .gitignore: add `.turbo`, `*.tsbuildinfo`, and `/.fork-update` (the local
patch bundle for the feedsbrain/face-api.js fork, not part of the app).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R84aj1GZ2yuPGqpioL1kfM
MIGRATION.md §1, §2, §4, §6 — the dependency half. The regenerated
package-lock.json can't be split per section, so all version moves land in one
commit:

- face-api.js -> `github:feedsbrain/face-api.js#master`, pinned in the lockfile
  to commit 7cc8a41 ("chore: make package git-installable"). No @tensorflow/tfjs
  added: the fork depends on tfjs-core + backend-cpu + backend-webgl itself and
  its ES build self-registers a backend.
- react / react-dom 17 -> 19; @types/react(-dom) 19; add @types/node 24.
- antd 4 -> 6; add @ant-design/cssinjs + @ant-design/nextjs-registry.
  Drop @ant-design/icons (was imported nowhere).
- next 11 -> 16; eslint 7 -> 9; eslint-config-next 11 -> 16; typescript 4 -> 5.9.
  Drop babel-plugin-import and next-plugin-antd-less.
- add engines.node ">=20.9.0"; `lint` script `next lint` -> `eslint`
  (next 16 removed `next lint`).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R84aj1GZ2yuPGqpioL1kfM
MIGRATION.md §2. `React.FC<{}>` + the explicit `React` import -> plain arrow
component. (DetectionLayout / WebcamDetect get the same treatment in the App
Router commit, where they also gain other App Router / antd 6 changes.)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R84aj1GZ2yuPGqpioL1kfM
MIGRATION.md §3 and §4 — inseparable because the antd 6 wiring lives in the new
App Router files.

Next 16 / App Router:
- delete .babelrc.js (re-enables SWC + Turbopack; a stray babel config silently
  pulls Babel back in) and drop the babel-plugin-import usage.
- next.config.js -> next.config.mjs, Less wrapper removed (drop
  next-plugin-antd-less); `output: 'standalone'` deliberately not set (it warns
  under `next start`, which start:prod relies on).
- delete src/pages/*. Add src/app/layout.tsx (root <html>/<body>, metadata),
  src/app/page.tsx (server component -> <CameraDetection />),
  src/app/api/hello/route.ts (Route Handler replacing pages/api/hello.js).
- src/components/CameraDetection.tsx: 'use client' wrapper doing
  dynamic(() => import('./WebcamDetect'), { ssr: false }) inside DetectionLayout
  — keeps face-api.js / TF.js (which touch window/document at import) off the
  server; a Server Component can't pass ssr: false.
- WebcamDetect.tsx: 'use client'; `router.events` is gone in the App Router, so
  the mount effect's cleanup calls stopVideoCapture() directly (+ an `active`
  flag so a late loadModels().then() can't start the camera post-unmount).
  start/stopVideoCapture -> useCallback declared before the effects;
  self-recursive setTimeout retry -> hoisted inner `attempt()`; `currentModel`
  state (setter only ever called in an effect — react-hooks@7 error) -> plain
  `const currentModel = model ?? 'mobilenet'`; typed refs.

antd 4 -> 6:
- SSR style extraction: <AntdRegistry> from @ant-design/nextjs-registry in
  layout.tsx (App Router equivalent of the old _document StyleProvider).
- src/styles/variables.less (@primary-color) -> deleted; theme token moves to
  src/app/providers.tsx ('use client' ConfigProvider,
  token.colorPrimary '#14424d').
- prop deltas actually hit: <Card bordered={false}> -> variant="borderless";
  <Space direction="vertical"> -> orientation="vertical".

DetectionLayout.tsx: React.FC<Props> -> ({ children }: Props), stale
eslint-disable comments removed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R84aj1GZ2yuPGqpioL1kfM
MIGRATION.md §5. tsconfig.json: target es5 -> ES2022; moduleResolution
node -> bundler; add incremental, plugins [{ name: "next" }], paths
@/* -> ./src/*; include .next/types. `strict: false` kept (typed refs are
enough; tightening is a follow-up). next-env.d.ts picks up the App Router
type references; `next build` also flips jsx preserve -> react-jsx — expected,
left as-is.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R84aj1GZ2yuPGqpioL1kfM
MIGRATION.md §6. Next 16 removed `next lint` and `next build` no longer lints.
Delete .eslintrc.json; add eslint.config.mjs extending
eslint-config-next/core-web-vitals (v16 ships flat config, bundling next +
next/typescript) plus an ignores block. Not wrapped in FlatCompat —
compat.extends() on the already-flat array throws "Converting circular
structure to JSON". (`lint` script -> `eslint` landed with the deps commit.)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R84aj1GZ2yuPGqpioL1kfM
MIGRATION.md §7. Base node:14.17.3-buster* -> node:24-bookworm-slim (both
stages). Build stage installs git (needed to resolve the
github:feedsbrain/face-api.js dependency) then `npm ci`. Runtime stage copies
node_modules / .next / public / package*.json / next.config.mjs from the build
stage instead of reinstalling; CMD ["npm","run","start:prod"] (still
`next start -p 80`). No standalone output (see §3). The version.json `sed`
patch is kept.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R84aj1GZ2yuPGqpioL1kfM
MIGRATION.md §8. The workflow only runs `docker build` on a self-hosted
runner, so the Node bump rides along inside the image.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R84aj1GZ2yuPGqpioL1kfM
MIGRATION.md §9. Rewrite README for the new stack (fix stale "standalone"
wording — standalone was tried and reverted). Add SPEC.md (as-built
description), MIGRATION.md (step-by-step record), and AGENTS.md / CLAUDE.md
(the Next-generated "this is not the Next.js you know" agent note + @AGENTS.md
include).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R84aj1GZ2yuPGqpioL1kfM
@feedsbrain
feedsbrain merged commit f243627 into main Sep 9, 2026
1 check failed
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.

1 participant