Skip to content

2025 Tooling Retrospective

Year-end judgment on the 2025 tooling arcs, what held up across types, lint, frameworks, and tests, and what I would not repeat.

5 min read
Retrospective
Tooling
TypeScript
Biome
Vitest
Playwright
Vite

Closing out 2025 means saying what the year’s toolchain posts actually taught: JSDoc and the TypeScript leap, ESLint/Prettier and Biome pilots, Vite/SPA foundations, React 19 timing, and the testing line from trophy through Vitest to Playwright.

What held up

Strict TypeScript as a product boundary. The March leap and strict config posts still hold: brands and generics helped when ids crossed package edges; they became ceremony when applied to every pixel prop. Keep constructors at the edge; skip decorative brands.

Shared lint/format contracts in the monorepo. Flat config and pre-commit work paid off when one package’s rules matched CI. They failed when apps forked configs "temporarily." Biome’s late-year pilot only made sense after measuring ESLint time and staging shadow CI, slogan "one tool" did not.

Vitest inheriting Vite resolve. Parallelism and workspace setup mattered less than not forking aliases. Fast unit/integration feedback kept Playwright honest as the expensive layer.

Playwright for journeys fakes lie about. Page objects and storage-state auth are December’s refinement of October’s trophy, not a replacement for Testing Library.

ts
// The year’s testing posture in one sketch, illustrative // unit: pure mappers, branded parsers // integration: providers + forms + accessible names (Vitest + Testing Library) // e2e: auth cookies, navigation, multi-step checkout (Playwright)

What I would not repeat

MistakeWhy it hurtPrefer next time
Tooling + mass format in one PRReviewers stop readingSeparable PRs (Biome lesson)
Dual lint with no sunsetPermanent taxPilot → exit criteria → cut
Present-tense preview compilersTimeline fictionBridge language; park TS 7 for 2026 dates
Only-E2E coverageSlow feedback, hidden unit bugsTrophy budget, not dogma
Framework bake-offs without constraintsHot takes, no decisionName constraints first (SSR? islands? team size?)

Decision criteria that survived contact

I kept four questions on a sticky note through the year:

  1. What failure ships if we skip this tool or test layer?
  2. Who owns the config when it breaks on Monday?
  3. Can CI and local run the same binary and policy?
  4. Is this a bridge, a default, or a preview?

If (4) is confused, you get November’s anti-pattern: treating a bridge TypeScript release like a native-compiler cutover, or treating a Biome pilot like a finished migration.

What I am still carrying into 2026

  • oxlint / oxfmt as a measured comparison, not a vibe switch, calendar already parks them after CI/delivery basics in Q1.
  • TypeScript 7 / tsgo only after real beta/RC dates on the integrity doc. The November bridge post exists so we do not freestyle that timeline.
  • Visual regression as a scoped design-system net, not a full-site screenshot religion.
  • Delivery arc in January: reusable workflows and preview deploys so the year’s config work has a place to run.

The through-line is boring on purpose: measure, name an owner, label previews as previews, and delete dual stacks when the pilot ends. Excitement without those habits is how tool blogs outpace production.

Open fact questions

Numbers I do not have yet:

  • Wall-clock ESLint vs Biome on the real monorepo runners?
  • Flake rate of Playwright before/after storage-state auth?
  • Bundle / CI minutes before and after any Vite major?
  • Which packages still carry intentional ESLint exceptions after Biome pilots?

Paste evidence when it exists. Until then, criteria beat borrowed percentages.

How the year stacked up

  • Types: JSDoc, the March leap, strict config, generics, brands, the 6.0 bridge
  • Lint: ESLint+Prettier, flat config, hooks, perf work, Biome look, Biome migrate
  • Apps: SPA/MPA trade-offs, Vite, SSR plugins, Astro, framework comparison, React 19
  • State: TanStack router/query, client vs server boundaries
  • UI: tokens, a11y libs, layout, forms, toasts, boundaries, CVA/clsx
  • Test: trophy, layers, Vitest, Playwright page objects, auth fakes, visual regression

Nothing here requires claiming a single "best stack." It requires showing you can retire tools without mythology.

Failure modes of retrospectives

Victory lap without scars. If every tool "was a win," you are writing marketing. Keep at least one retired approach (JSDoc-only for app code; only-E2E suites; permanent dual lint).

Rewriting history for 2026. oxlint / oxfmt and TS 7 slots are on next year’s calendar. Do not smuggle them into a 2025 wrap as if they already shipped as defaults.

Checklist without judgment. A bullet list of versions is not a retrospective. Criteria and refuse-lists are.

Continuity

Year-end judgment sits between auth-E2E craft and visual regression close. Delivery/CI follows: pipeline design, then reusable workflows. Lint's rust-shaped sequel (oxlint) is a measured comparison for later.

Takeaway

Tooling pays off when CI and local share a contract, previews stay labeled previews, and every pilot has an exit, not when the blog has a new logo each quarter.