pnpm bundle:check applies three explicit policies:
- Locked entries are ordinary TanStack Charts consumers that optional
features must not affect. Their minified and gzip bytes must match
universal-baseline.jsonexactly. - Budgeted entries isolate an optional chart feature or D3 capability and enforce a feature-specific gzip ceiling. An incremental budget compares two complete consumers so shared compression is represented honestly.
- Measured entries are comparison libraries, applications, or exploratory D3 kernels. They are reported without defining a TanStack product ceiling.
Every package entry in
measure-bundles.mjs declares one policy.
New marks and optional capabilities need an isolated budgeted entry. They must
leave the locked entries byte-identical.
The retained-input gate reads esbuild's output contributions rather than its parsed input list. This distinguishes code that contributes bytes from a zero-byte re-export. The compact-scale fixtures require their exact subpaths and reject sibling scale implementations. The React base rejects tooltip and portal code, the tooltip consumer rejects portal code, and the portal consumer may add only its transport module over the tooltip consumer. Ordinary line, compact-scale, and tooltip kernels also reject all transform modules.
The compact linear scene and React consumer are both locked and budgeted. The
scene has a 12.46 KiB gzip ceiling. The React compact-scale line consumer has a
31.03 KiB ceiling with React and React DOM external. d3-array tick helpers are
allowed only in the compact linear path; categorical compact-scale kernels
reject every D3 runtime input. All compact fixtures reject d3-scale,
d3-format, d3-interpolate, d3-color, and internmap.
Painted-geometry interaction is part of the default scene and host contract across DOM, Canvas, and native rendering. Its isolated resolver has a 2.9 KiB gzip ceiling. The locked shared-host entries record the reviewed integration cost, while noninteractive consumers retain only the small scene-compiler portion of that contract.
Cartesian axis-title styling is also part of the shared scene contract. Its static SVG fixture adds no retained modules over the ordinary line consumer and keeps authored title options under a 0.25 KiB incremental gzip ceiling.
Configurable Cartesian grid and axis-line strokes, including geometry-aware automatic margins, are also part of the default scene contract. Their reviewed shared-path cost is recorded in the locked entries and complete-consumer budgets. In the cumulative release, guide styling adds 504 gzip bytes to the compact scene and 516 bytes to the DOM host. Its complete-consumer ceilings retain roughly 30 bytes of headroom above the measured output.
Continuous viewports and the controlled interaction controller are also part of the default scene and host contracts. Default static SVG consumes scene clips and gradients. Their reviewed shared-path cost is recorded in the locked entries and the corresponding complete-consumer budgets. Rolling path planning remains confined to the opt-in motion renderer, whose complete SVG budget is 22.45 KiB gzip. The cumulative styling, focus-motion, and radial-gradient integration measures 22.42 KiB for this optional renderer. The composite SVG consumer measures 30.33 KiB after guide styling, with a 30.36 KiB ceiling. Radial resources add 112 gzip bytes to the static SVG consumer and 124 bytes to the DOM host. Scene-only consumers remain unchanged apart from one byte of compression variation.
Every public transform family has an isolated budget and retained-input
allowlist. Numeric and 2D bins may retain d3-array, and row stacks may retain
d3-shape. Other transform entries reject those dependencies, while every
granular entry rejects unrelated transform families. The suite fixture proves
the common families still compose without pulling calendar bins or advanced
reducers into the default set.
Non-cartesian capability subpaths follow the same policy. Polar and geographic entries measure complete scenes through static SVG: a minimal arc, first-party pie allocation, full scale-backed gauge composition, a scale-backed polar line and scatter composition, and projected GeoJSON. Atlas datasets remain application-owned inputs rather than chart-package dependencies. The locked Cartesian entries prove those D3 geometry modules remain opt-in.
Polar and geographic focus states reuse the initialized-mark state resolver. The complete static SVG consumers add 35 gzip bytes for geographic shapes, 75 for arcs, 170 for the gauge, 164 for radial labels, 57 for radial bars, and 78 for polar line/scatter composition. Their optional ceilings retain about 20 to 35 bytes of headroom. Locked Cartesian consumers stay byte-identical.
The advanced custom-mark scale-value factory follows the same rule: its subpath has a dedicated budget, while ordinary chart entries must retain zero bytes from it.
The optional interaction measurements include the practical granular imports:
d3-brush or d3-zoom together with d3-selection. The standalone kernels
remain comparison baselines. The exact interaction/brush fixture measures
the first-party behavior over the ordinary DOM host and proves its D3 runtime
does not enter root, universal, or unrelated host consumers. It adds 19.70 KiB
gzip under a 20 KiB incremental cap.
The exact interaction/zoom fixture adds 20.24 KiB gzip over the ordinary DOM
host under a 20.25 KiB incremental cap. It retains the controlled signal, shared
interaction axis and range kernels, the zoom controller, and private D3 Zoom
runtime. Root, universal, cursor, brush, native, and unrelated consumers retain
no zoom code.
The exact interaction/cursor fixture also measures over the ordinary DOM
host. It adds 3.71 KiB gzip under a 5 KiB incremental cap. It requires only the
controlled signal, shared scale-interaction axis, cursor controller, and
guide-node kernel. It rejects the datum focus guide, brush and D3 runtimes,
tooltip, legend, and selection modules.
The exact interaction/handle fixture adds 3.65 KiB gzip over the ordinary
DOM host under a 5 KiB incremental cap. It retains only the controlled signal,
shared candidate-axis and value-cloning kernels, and handle controller. Root,
universal, cursor, brush, zoom, native, and unrelated consumers retain no
handle code or D3 runtime.
The controlled-signal fixture measures 0.09 KiB gzip against a 0.25 KiB cap. The interactive categorical legend fixture adds 2.53 KiB gzip over the DOM host and has a 2.6 KiB incremental cap. Both retain only their declared exact subpath modules.
The static categorical legend fixtures measure the default legend separately
from the tree-shakeable colorLegendItems() presentation. The configured
fixture covers centered flow layout, custom label paint, and mixed square and
line-dot indicators through the exact @tanstack/charts/legend subpath. Their
retained-input gates reject the interactive legend, host renderers,
interactions, and D3 geometry. The default fixture has a 1.8 KiB gzip ceiling;
item presentation adds 1.85 KiB gzip and has a 1.9 KiB ceiling. That increment
includes deterministic fallback measurement with host typography when a text
measurer is missing or returns invalid metrics, plus measured title and row
extents that keep scaled or asymmetric text from overlapping.
Passing the host layout into the legend context adds 27 minified bytes and 4 to 7 gzip bytes to shared scene consumers. The locked baseline records that reviewed cost. Isolated consumers that were already within a few bytes of their ceilings have matching 0.01 to 0.02 KiB budget adjustments.
Update the universal baseline only after reviewing why a shared path changed:
pnpm bundle:update-baseline
pnpm bundle:checkA decrease also requires an update. This prevents a later regression from silently consuming size that an optimization recovered.