Component libraries and UI infrastructure
Third-party UI dependencies are infrastructure too
Wrap defaults, not upstream APIs. Use composable configuration factories to keep third-party engines powerful without building fragile proxy wrappers.
Complex UI dependencies solve hard problems. A charting engine, rich-text editor, or virtualized grid brings years of accessibility work, cross-browser quirks, and performance tuning that no product team should rebuild from scratch.
They also bring architectural liability: their own configuration trees, event models, styling systems, and release cadences. When we integrate them without a clear boundary, we risk falling into one of two traps.
Two common integration traps
The first trap is the uncontrolled direct import. Feature teams across multiple repositories install the library directly, styling tooltips with local CSS and wiring callbacks however they see fit. When a minor version bump renames an option or changes keyboard focus semantics, the breakage ripples across dozens of unrelated pull requests.
The second trap is the monolithic proxy wrapper. An infrastructure team creates <MetricsChart /> or <DataGrid /> to hide the dependency behind a clean internal facade. It does not take long for the props to pile up:
<MetricsChart
showLegend={true}
legendPosition="bottom"
enableCrosshair={false}
donutHoleSize={0.8}
onSliceClick={handleClick}
/>
Every new product requirement becomes a ticket for the infrastructure team to proxy another upstream configuration knob. The team ends up maintaining a second, worse version of the library's documentation.
The middle ground: composable defaults
The architectural answer is composition: standardize the defaults while preserving direct access to the engine's configuration model.
Instead of hiding the third-party library behind a rigid wrapper component, we can provide composable configuration helpers. These helpers inject design tokens, accessible labels, and shared conventions into the native configuration tree without obscuring it:
const chartConfig = composeChartConfig(
withTheme(designTokens),
withDonutStyle({ holeSize: 0.8 }),
withSeries(segmentData),
{
title: { text: 'Active subscriptions by tier' },
plotOptions: { pie: { dataLabels: { enabled: false } } },
}
);
composeChartConfig merges shared product decisions: palette tokens, font scales, and tooltip accessibility. The resulting output is still a standard Highcharts configuration object. When a feature needs a niche capability such as custom SVG annotation markers, we can configure it directly without waiting on a platform team to add a prop to a proxy wrapper.
The composition boundary
- Standardize
- Tokens, themes, and shared conventions
- Leave open
- The engine's native configuration tree
Treat third-party engines as infrastructure
Third-party UI libraries are dependencies of the platform, not individual product features. They require explicit ownership:
- One version across the workspace: Upstream upgrades should be tested and landed in infrastructure packages, never fragmented across feature branches.
- Tokenized visual layers: Colors, borders, and fonts in third-party widgets must draw from the shared token pipeline, matching the rest of the UI kit.
- Preset factories over wrappers: Shared behavior travels through composable configuration presets, avoiding rigid wrapper components that proxy upstream options.
By separating shared defaults from engine configuration, our product teams get consistent, accessible components out of the box while keeping the full power of specialized tools within reach.