Skip to main content

Engineering Quality

How do you know the codebase is healthy — not from reading the code, but from measuring it?

Every threshold below is pass/fail. If a number is above threshold, the system is degrading and the fix has higher priority than new features. These benchmarks parallel the UI Design thresholds but measure structural and runtime health of the code itself.

Benchmark Context

Use this page with Performance to connect engineering quality gates to business outcomes. A codebase that passes these thresholds ships faster, breaks less, and costs less to change.

STANDARDS (this page)    → defines "module count < 200 per route"

BUILD (best practices) → developer follows checklists

DETECT (anti-patterns) → catch violations before they compound

MEASURE (metrics) → track trends over time

IMPROVE → update the standard

Module Budget

Every page has a practical ceiling. Exceeding it degrades dev-server startup, HMR speed, and production bundle size.

#CheckThresholdHow to Measure
1.1Modules per route<= 200next build output or custom module count script
1.2No single import pulls entire dependency graph0 transitive barrel blowoutsTrace import chain from page to leaf
1.3Module count trendFlat or declining per sprintTrack per-route counts in CI

Root cause of blowout is almost always a barrel import from a composition library that transitively pulls everything into every page that touches it.


Bundle Size

#CheckThresholdHow to Measure
2.1Initial page load<= 1MB transfer sizeNetwork tab, throttled to 3G
2.2JavaScript per route<= 200KB gzippednext build output per page
2.3No bundle regressionSize unchanged or reduced per deployCI diff against previous build
2.4Tree-shaking verifiedUnused exports not in production bundleBundle analyzer

Type Safety

#CheckThresholdHow to Measure
3.1Full monorepo typecheck passes0 errors on tsc --buildCI typecheck step
3.2No any or @ts-ignore added0 new instances per PRGrep diff for any and @ts-ignore
3.3composite: true on all library tsconfigs100% complianceGrep tsconfig.lib.json files
3.4rootDir aligned with include0 mismatchesCompare fields in each tsconfig
3.5No skipLibCheck: true in root configAbsent from tsconfig.base.jsonDirect check

TypeScript project references live or die by composite and rootDir alignment. Disabling them silences errors temporarily but creates cascading failures in CI.


Dependency Graph

#CheckThresholdHow to Measure
4.1Layer boundaries enforced0 violations on nx lint@nx/enforce-module-boundaries
4.2eslint-disable count for boundary rulesTrending to 0Grep and count per PR
4.3Every library has tags100% of project.json files have non-empty tagsAutomated check
4.4No wildcard dependency constraints0 "*" in onlyDependOnLibsWithTagsGrep eslint config
4.5Domain depends on nothing external0 framework imports in domain layerbannedExternalImports

The dependency direction for hexagonal architecture: Composition → Application → Domain ← Infrastructure. Domain is the center. Everything points inward.


Barrel Hygiene

#CheckThresholdHow to Measure
5.1No export * outside entry-points0 instancesGrep for export * excluding entry-points/
5.2Consumers use subpath imports0 root barrel imports from appsno-restricted-imports lint rule
5.3No nested internal barrels0 index.ts files in src/lib/*/Find internal re-export files
5.4No cross-boundary src/ imports0 imports via ../libs/*/src/ pathsGrep for src/ path imports

Barrels are not inherently bad — undisciplined barrels are. The rule: barrels as curated public API only, never as convenience re-exports.


Build Performance

#CheckThresholdHow to Measure
6.1Full typecheck<= 120 secondsCI timing
6.2Affected build<= 60 seconds for typical PRnx affected --target=build timing
6.3Dev server cold start<= 15 secondsLocal measurement
6.4HMR update<= 2 secondsLocal measurement
6.5CI cache hit rate>= 80% on non-first buildsNx Cloud or CI cache stats

Core Web Vitals

Runtime performance of shipped pages. See Next.js Performance for the full checklist.

#CheckThresholdHow to Measure
7.1Largest Contentful Paint<= 2.5sLighthouse
7.2Interaction to Next Paint<= 200msLighthouse
7.3Cumulative Layout Shift<= 0.1Lighthouse
7.4First Contentful Paint<= 1.8sLighthouse
7.5Total Blocking Time<= 200msLighthouse

Enforcement Layers

Stack these so violations are caught progressively earlier. Each layer catches what the previous missed.

LayerWhat It CatchesWhen
ESLint module boundariesCross-layer imports, banned externalsIDE + build
ESLint import restrictionsRoot barrel usage, src/ path importsIDE + build
ESLint syntax restrictionsexport * usageIDE + build
Pre-commit hooksArchitecture grep checks, eslint-disable countBefore push
Full typecheckTS6305, TS6059, TS2305 cascadesBefore push / CI
Module count scriptPer-page module budget regressionCI
Production buildBundle size, tree-shaking verificationCI

How This Works

ConceptApplication
StandardThis page defines "healthy codebase" in measurable terms
ProtocolLint rules, CI checks, and audits recreate expected outcomes
BenchmarkA codebase passes with 0 violations across all 7 categories
TriggerAny FAIL triggers a fix before shipping new features

Context