Skip to main content
Status: Accepted Date: 2026-02-06 Deciders: Reflections Maintainers

Context

The codebase spans API, worker, web, and shared packages. Divergent runtime/build standards would increase deployment variance and type/runtime mismatches.

Decision

Adopt and enforce the following repository-wide standards:
  • Node.js 20+ runtime baseline.
  • ESM modules ("type": "module") across apps/packages.
  • TypeScript strict mode for compile-time safety.
  • tsup for package build outputs and dist entrypoint exports.
  • pnpm as package manager with locked workspace version.
  • Shared timeout/deadline budget policy: remainingBudget in @reflection/shared/timing is the canonical deadline utility; new timeout math must reuse it rather than introducing local deadline calculators.

Alternatives considered

Alternative 1: Mixed runtime versions per app

Pros:
  • App teams can move at different speeds.
Cons:
  • Harder reproducibility and higher CI/runtime drift.
  • More matrix complexity in local and CI environments.

Alternative 2: CommonJS for backend packages

Pros:
  • Broad historical compatibility.
Cons:
  • Interop friction with modern ESM dependencies.
  • Inconsistent import patterns across repository.

Alternative 3: Per-package custom build tooling

Pros:
  • Fine-grained package-level optimization.
Cons:
  • Significant maintenance overhead.
  • Inconsistent output semantics and slower onboarding.

Consequences

Benefits:
  • Consistent local/CI/prod runtime expectations.
  • Reduced packaging and import mismatch issues.
  • Predictable build outputs for inter-package consumers.
Costs:
  • Requires tooling alignment and periodic version coordination.
  • ESM-only constraints can require adaptation for legacy integrations.

Implementation notes

  • Runtime constraints are declared in root package.json and .nvmrc.
  • Package build conventions are enforced by scripts in packages/*/package.json.
  • Type standards are centralized in tsconfig.base.json.