January 15, 2019
  • Perspectives
  • Design Systems
  • stencil

Build Your Next Design System with Web Components

Max Lynch


Few things in the frontend world are as hot as Design Systems, the idea of building a design spec or library of reusable components that can be shared across a team or company. Design Systems enforce style and branding guidelines, reduce design fatigue for engineers, and consolidate component engineering to one single set of components and a team that builds them. Basically, they help teams manage design at scale.

Smart companies like Hubspot, Salesforce, and Intuit have invested considerable resources in not only building their own internal design systems, but also sharing their knowledge with the rest of the frontend design world.

I’m not going to convince you that Design Systems are valuable since the proof is pretty easy to find. Rather, assuming you agree your company needs a Design System, I want to talk about the hard decisions that need to be made in order to build one.

Design or Code?

First, you need to decide if your Design System will be just a design specification, or a set of real code components.

There are essentially two major schools of thought when it comes to Design System implementations:

The first is design spec-focused, where designers build assets in a prototyping/UX tool like Figma or Sketch, and then put those design assets and concepts in a guide that specifies how engineers should implement those designs, but without any accompanying engineering implementation. The most famous example of this is Google’s Material which exists first and foremost as a design specification, with specific platform implementations of that specification made available as derivative works.

The other school of thought is that your Design System should be a real code asset that engineers can pull from as they build their apps. Generally, these components are built in a cross-platform, web-first fashion so they can be used across all the platforms your team cares about.

For most organizations, having only a design spec isn’t going to be enough, and leaves too much onus on engineers to faithfully implement the spec while also building apps with those components. Instead, teams will be more successful with a shared library of real code components a single team can maintain and any app development team can pull down and use without having to think about the actual design and implementation of those components.

How do I build a real code Design System?

Once you decide to build out a set of reusable components instead of just a design spec, the question then becomes how do you actually build that?

In the web world, there are various ways to build a set of shared components. One of the earliest was the approach popularized by Bootstrap, where the right incantation of HTML markup combined with CSS classes and jQuery results in a structured framework for frontend design. As most Bootstrap users know (and we know, we built a design tool for Bootstrap) that process can get unwieldy and leaves too much room for mistakes.

Over the last five years or so, a better option emerged: building a Design System in a specific frontend framework like Angular or React or Vue. In this approach, components could be built and shipped in such a way that an engineer just had to import and use them, and often could not make any modifications to the underlying components or make any mistakes using the components.

Why You Should Reconsider Building Your Design System on Angular, React, or Vue

While building a Design System in Angular, React, or Vue is quite a bit better than the too-open-ended approach used in Bootstrap, it has one major flaw: it only works if the rest of your company has standardized on that single framework!

While these frameworks are wonderful for building apps and most teams should be using one, they might not be right for most enterprises when it comes to building a set of components that will be distributed across teams, many of which are making their own technology decisions or will likely in the future.

Additionally, given that these frameworks evolve quickly, app dev teams may decide to move to newer versions of the framework independently of other teams, which could introduce compatibility issues with the component distribution.

It really has nothing to do with the merit of these frameworks, but the simple fact that a team that picked, say, Angular, can’t just use React components in a first-class way. Even if your company has standardized on a single frontend tech stack, we all know that the industry changes quickly and what seemed like a sure-fire choice today could change significantly in a few years.

One Component Model to Rule Them All

If Angular, React, or Vue isn’t the right choice for building a set of reusable components, then what is?

The answer is Web Components, a set of standardized APIs available in all modern browsers that makes it possible to build rich, JavaScript-powered components, and distribute them as simple HTML tags that any web developer or designer can use regardless of the frameworks or libraries they choose to use on top.

Web Components are standardized technology, and are natively supported in modern browsers. These components run on nearly all mobile devices and desktop browsers today, and since they are baked right into the browser, you don’t need a specific frontend framework to use them. For browsers that don’t natively support them, polyfills are available to fill in the gaps (more on that in a minute).

Any examples?

Web Component support is relatively new (2018 being the first viable year), so teams looking to standardize their Design System on top might struggle to find examples in the wild.

One big example is Ionic Framework version 4, the web-based UI Design System that helps teams build apps for iOS, Android, Desktop (Electron), and the Web (Progressive Web Apps, etc.).

Historically, Ionic shipped as a set of pre-made AngularJS and then Angular 2+ components. Any team using AngularJS or Angular could import Ionic’s components and use them in their app. This worked well while Angular was the only game in town, but the frontend ecosystem quickly evolved and suddenly teams were using way more than just Angular. Ionic found itself siloed and unable to help the largest number of web developers build apps.

To solve this problem, the Ionic team decided that the right decision for a Design System like Ionic was to not “bind” to a specific framework, requiring any users of Ionic to use that framework in conjunction with it. Rather, the components should be built using technology that would work in any framework, and ideally be built on top of web standard APIs that would endure for decades.

What’s fascinating is how similar Ionic’s problem is to the one we hear from teams at companies that also built their own design systems on top of a single framework. What made sense a few years ago ended up being the wrong solution as the frontend ecosystem evolved and their app development teams wanted to try new frameworks or even upgrade their existing framework.

We believe so much that Web Components are the right solution to this problem that we’ve invested in building out tooling like Stencil to make it even easier to build and distribute Design Systems with Web Components. Stencil not only makes it easy to build Web Components, but it also automatically manages polyfills for browsers that need them, along with grouping components into “collections” that can be loaded together to improve performance. It also produces components that are very small in terms of file size and exceed performance standards for the modern Progressive Web App era. Unlike a framework, stencil simply provides a structured way to generate Web Components for the purpose of building Design Systems, it likely won’t be used as the “framework” for the rest of your app.

But don’t just take our word for it. There’s a quiet surge in real-world usage of Web Components for design assets, and it’s clear that this is an approach that is highly appealing to top technology companies (take GitHub, for example).

What about Angular Elements, Vue Web Components, etc.?

Two exciting projects in the frontend world are Angular Elements and Vue’s Web Component output support. These projects allow Angular and Vue to output Web Components with the framework being “self-contained” in the components that are generated or to link with the framework externally.

I am optimistic that these projects will provide a good middle ground for teams that have existing component systems built on these frameworks, and wish to “unlock” them from the framework for teams that wish to consume the components outside of these frameworks.

Something to keep in mind with these projects: currently, they either bundle in the framework itself (Angular), or require the framework to be available as a global variable (Vue). To us, that makes them not an ideal choice for Design Systems that wish to be as lean and framework-agnostic as possible. Additionally, these projects do not automatically manage polyfills for clients meaning you’ll need to manage those yourself and also make sure you only serve them to clients that need them.

That being said, we are optimistic these projects will improve over time and make these frameworks good choices for Design Systems, despite not being ready today.

Build your Design System with Web Components

At Ionic, our business is building a leading real code Design System that teams can use to build cross-platform apps using standardized web technology. Every day we talk to more and more enterprises that want to “build their own Ionic” on top of Ionic, and come to us for help on how to do that.

As we talk with teams, it’s clear that the old approaches to solving this problem weren’t scaling. They wanted to invest in a component model that would work with any technology their teams chose to use and would be stable and last for many years to come, regardless of what happens in the frontend ecosystem.

When we bring up using Web Components to solve that problem, these teams are often intrigued and remark that this is exactly what they are looking for.

If you’re also intrigued, getting started building with Web Components is easy:

Getting Started with Web Components

There are many tutorials for building with new Web Component APIs. We recommend starting with Google’s Custom Elements overview for an introduction to the low-level APIs involved. After that, check out Stencil, LitElement, or SkateJS for some tools/libraries that simplify using the low-level APIs.

Build your own Ionic with Ionic

Finally, because Ionic Framework 4 is itself a Design System, it’s possible to use it as a base for your own Design System. And because it’s built on Web Components, it has all the benefits described above.

That means instead of investing considerable resources in building out a custom set of components and optimizing them, you can use the industry-leading Ionic Framework 4 as a base for your own Design System. We’ve invested a ton of time in exposing theming and customization features for each component, making it easy to modify and quickly apply your branding without having to break open the components to do it.

Plus, Ionic Framework 4 components work on iOS, Android, Desktop with Electron, and anywhere the web runs (like Progressive Web Apps). You get all of that for free.

If you’re a team or company that wants to build their own cross-platform design system on top of Ionic Framework, we can help! Get in touch and we’d be happy to see if Ionic can help your team build and scale a Design System using open web technologies and Ionic Framework 4.

Regardless, we hope you’ll consider building your next Design System with Web Components so all web developers can use it no matter what frameworks and libraries they choose to use.

Max Lynch