Building a Design System Across Teams
- Design Systems
- Frontend
- Engineering Leadership
- Web Components
The symptom was obvious before the cause was. Different parts of the product looked slightly different. Not dramatically — a slightly different button shape here, a different modal behaviour there, slightly inconsistent spacing. Nothing that would make the front page of a design blog. But for users moving through the product, and for designers trying to maintain any coherent visual language across it, the drift was real.
The underlying cause was structural. Different frontend teams had built their UIs in parallel, each making local decisions that made sense in context but compounded over time. When a designer wanted to update something — a hover state, a form pattern, a component layout — the change had to be implemented in multiple places by multiple teams, often inconsistently, always slowly.
A central design system was the obvious answer. What was less obvious was how to build it in a way that teams would actually adopt.
The collaboration problem
Most design system efforts fail not because of the technology, but because of the ownership model. Engineering builds a component library, hands it to designers, and neither side feels fully responsible for it. Or the design side defines everything in Figma and engineering spends most of its time translating specs into components that don't quite match. The system becomes a negotiation surface instead of shared infrastructure.
We started with what looked like a technical problem: standardising the code that already existed and gradually extracting a shared system from it in close collaboration with UX. The goal wasn't to design an ideal system in isolation. It was to define one teams could adopt incrementally, with a migration path that was clear enough to work in real product delivery.
That became especially important because the work coincided with a large rebranding effort, moving customer frontends from the 1&1 brand to IONOS. Most applications had to be touched anyway. That gave us a narrow window to establish a stronger foundation for the future while also reducing the amount of one-off effort the rebrand would otherwise have required.
A technology choice driven by constraints
The first version of the design system was built with SASS, PostCSS, and Vanilla JS, delivered via CDN.
This wasn't an accident. IONOS had frontend teams working across different technologies — some on older stacks, some on newer frameworks. If we'd built the design system as a React component library, we would have solved the problem for React teams and created a new one for everyone else. A CDN-delivered bundle with no framework dependency could be adopted by any team, regardless of their tech stack. The design system could be a shared foundation precisely because it didn't impose a technology choice.
The tradeoff was encapsulation. CSS delivered through a CDN is global. You could include the design system and, if you weren't careful, its styles would bleed into your application's own styles. Component behaviour was JavaScript operating on DOM elements in the usual way — straightforward, but without the clean isolation that modern component models provide. For a first version, it was the right call. For a maturing system with more teams and more complexity, it wasn't going to scale.
What the first version revealed
The v1 approach taught us something important: a design system is not a project you finish. It's infrastructure that has to evolve with the product and the teams using it.
As adoption grew, so did the friction points. Teams reported style conflicts. Updating a component required coordination to ensure nothing broke downstream. The lack of encapsulation, which had been manageable with a few teams, became a genuine source of instability with more.
The next version of the design system is being built with Stencil.js — a framework for building native web components. Shadow DOM provides the encapsulation the first version was missing: component styles live within the component, not in the global stylesheet. Lazy loading means teams only pay the cost of the components they actually use, rather than loading the full bundle. And because web components are a browser standard, the framework-agnostic principle from v1 carries forward: any frontend technology can consume them.
The move to Stencil wasn't a rejection of the first approach. The first approach was a mandatory step on our journey, shaping collaboration and laying the foundation for the next chapter.