Installs TypeScript toolchain and configures it to accept every
existing .js file untouched. tsc --noEmit is green; the app runs
identically and nothing is deployed or rebuilt yet.
Config choices:
- extends @tsconfig/node20 (matches the runtime version)
- allowJs: true, checkJs: false — existing files pass through
- strict: false — tightened progressively on day 5, not day 1
- skipLibCheck: true — node_modules .d.ts quality varies, not our
job on migration day
- paths: { "@shared/*": ["./shared/*"] } — pre-wired for the
shared/types.ts file landing on day 2
Dependency notes:
- typescript 6.0.3 (current stable, released late 2025)
- @types/express pinned to ^4 because the app uses Express 4.21;
the default npm install picked @types/express 5 which doesn't
match runtime shapes for Request/Response
- @tsconfig/node20 for the known-good strict / module / target
triple for Node 20 LTS
- ts-node-dev for the new `npm run dev` script — transpile-only
mode, keeps startup fast
package.json script additions:
- build: tsc (compiles to dist/)
- typecheck: tsc --noEmit (CI-friendly)
- dev: ts-node-dev for TS-aware hot reload
- lint:refs: wraps the existing static reference linter
Left alone (no behavior change):
- start: still node server.js
- Dockerfile unchanged (prod still runs vanilla JS)
- All 54 backend .js files untouched
Day 1 scope matches the migration rule: no runtime behavior changes,
nothing deployed. Next: day 2 creates shared/types.ts and flips
server.js to server.ts.
Reference tag: pre-migration-v1 (commit 447eb78).