Our design system’s journey to framework independence
Two weeks ago, we announced the work we’ve been doing behind the scenes to build Clarity Core, a framework-independent design system based on web components. At a high level, these are our five key goals and drivers:
- Clarity is user-focused. Its design patterns are and will continue to be driven by our users.
- Clarity is committed to accessibility and inclusive design.
- Clarity is enterprise-ready and we think that raises the bar for usability.
- Clarity has always been and is committed to remaining open source.
- A big part of Clarity’s future will involve framework independence.
My colleagues have already written about our commitment to accessibility and the efforts to which we have gone as a team to build an inclusive library of components. Today we will address that last bullet point — framework independence.
What is framework independence?
A front-end framework is (generally speaking) code written by an outside group or organization that ships with a web application. A framework typically handles the following features:
- Routing: switching “pages” of the application without taking you to a new page
- Data-binding: when you change information in one place it shows up correctly in another
- State management: maintaining consistency of data so that everything remains as expected when you go from one page to another
Frameworks can do more than this, surely, but that’s the gist of what they do. And there are hundreds of them.
In the early days, Clarity rallied around Angular as a way to materialize our design system in a library complex, data-bound components and bring our product teams at VMware together on a common tech stack. This was a huge success for us as we saw the vast majority of products at VMware choosing Angular and Clarity to build their applications.
The good news is that we will continue to support and drive Angular adoption across the company. But the better news is that our patterns, services, and components will now be available to teams who rely on Vue, React, Ember, Elm, or any other framework.
We feel strongly that the future of all viable component libraries is framework independence and our plan is to deliver on this belief.
How are we going to do this?
Our plan is to deliver a core set of web components in an npm package we are calling Clarity Core. In addition to these components, the Clarity Core library will contain helpers, mixins, services, and utilities that are generally useful across Clarity Angular, Clarity Core, and Clarity Icons.
Clarity Core will become a foundational piece of the existing Angular library we have because Clarity Angular will reuse its services and components.
Why web components?
We know that custom elements can work across all the browsers we support and that this is the right time to embrace them as a foundation for the Clarity Design System.
How will this affect the Angular library?
Clarity Core will not affect consumers of the Clarity Angular at all. Even when Clarity Core components and services are used as a foundational piece of the Clarity Angular library, the teams who rely on Clarity Angular will not know or need to know that it is there.
The goal is to make this as minimally impactful to existing Clarity Angular applications as possible.
An Angular application should not know or care whether a Clarity component is written 100% in Angular or is built on top of a Clarity Core component.
Additionally, Clarity will always rely on frameworks to do what they do best because it would be counter-productive for us to try and rebuild a framework inside of a library of web components. Our #1 framework at VMware is Angular, so we are committed in the long-term to supporting and growing Clarity Angular.
I’ve had a hard time with web components in React. How does this help me?
For the last few months, members of the Clarity team have been doing a deep dive into integrating web components with React applications. At the end of our journey, we identified an architecture of “React wrappers”. We’ve reviewed this architecture with some of VMware’s best React developers to make sure we had their stamp of approval before moving forward.
How are you building this?
The Clarity team put a lot of effort into researching the best path forward for this library. In the end, we identified three key attributes that we wanted to preserve:
- The architecture of the Clarity Core components library would be familiar enough that contributors with experience working with Clarity Angular could contribute to Clarity Core without a steep learning curve.
- The APIs of the current Angular components would transfer as closely as possible to help manage situations where a current Angular component would be moving to the web component library.
- The code underneath would adhere as closely as possible to emerging web standards as we continue to bet on web standards for the future.
After several explorations into a variety of possibilities, we arrived at five foundations for the Clarity Core architecture. Note that the following is a deeper dive into the technical aspects of Clarity Core. If that’s not something that interests you, please jump forward to the next question.
2. Custom Properties
Additionally, custom properties are the most direct way to enable theming in a library of ShadowDOM encapsulated web components.
3. Lit Element
Lit element is an incredibly solid and light foundation upon which to build a library of web components. Lit is maintained by the Polymer team at Google and our esteem for this library has grown the more we have worked with it.
Besides being a very lightweight dependency, Lit follows web standards — which was important to us because we believe web standards are the future. It also feels great to have your sole, major dependency be such a thin layer above the code running in the browser itself.
Lit is more than syntactic sugar, but one would be excused for viewing it as a convenient base class and nothing more. The simplicity and transparency of Lit also support our desire to keep the architecture as easy to work with as possible.
4. Minimally Stateful
In our research, we wanted to make sure that Clarity Core components would be easy to use for product teams working in Angular or React. For extra credit, we also dove into Vue and a couple of other frameworks. We did hit a minor speed bump, however.
Angular’s views and change detection cycle are just different enough from React’s Flux architecture and Virtual DOM that the way a developer works in one framework may not necessarily follow in the other framework.
Sure, Angular developers have NgRx and can use that for state management combined with advanced (or some would say proper) use of RxJS to implement the Flux architecture in their Angular applications. But we do not have the luxury of only supporting one implementation of the Angular application architecture.
It also became clear early on that the current Clarity Angular library of components offers functionality tied to Angular. This constituted functionality that it would make no sense for us to replicate in a library of web components.
To be more specific, we are talking about features in Angular like reactive forms, routing, and two-way binding. While most frameworks have their own spin on these features, it became clear that most frameworks weren’t always in alignment on the details. In the end, we found there was no one ideal solution.
Our team now jokingly refers to the task of building frameworks-within-frameworks as “Frankenstein Angular” and have decided against re-building “framework features” into a framework-agnostic library of components.
Instead, we decided the best path forward was to adopt a strategy of being “minimally stateful”.
There are some features of a component that it would be tiresome to have to turn on and off from your application. Being “minimally stateful” means we will handle those tasks for you, track them for you, and communicate any changes so you can keep your application’s state current if you need to.
But we also concluded that any features of a component that an application developer might reasonably want to circumvent should be driven and managed by the application’s state — not from within the component.
As a consequence, a datagrid in Clarity Core won’t manage large chunks of data like the datagrid in Clarity Angular does. Likewise, a wizard in Clarity Core won’t be managing the state of its pages and the user’s ability to navigate them in the same way either.
While this may be a little surprising for developers used to monolithic, black-box components that gobble up hundreds of lines of JSON configurations, we feel confident that this will ultimately be liberating for application developers because it puts a level of customization in their hands that other libraries cannot match.
It also lowers the requirements for developers to invest in learning a component library API — especially one that may run counter to their framework of choice.
5. Reduce Through Reuse
Ultimately, Clarity Core will be a refinement of the vision that resulted in the current library of Angular components.
The intent with this new initiative is not to duplicate the effort with an unrelated library that requires separate support, maintenance, and its own entire team. The real value of Clarity Core, for us, is in what we can abstract and reuse.
There are going to be some components in Clarity Angular that will always be built on top of Angular–even if they have a replicate in Clarity Core. But many, if not most, components in our Angular library will become wrappers for Clarity Core components. This will help our team differentiate between framework-driven features and core features of the components we deliver.
How do we get there?
We have a lot of work ahead of us and some effort towards fixing up the current Clarity architecture to allow for a new library of web components.
Presently, our roadmap to web components looks something like this:
CSS Custom Properties–3.0 release (Nov-Dec 2019)
Refactoring Clarity to use CSS Custom Properties is a big task — and one we completed just this month! We started by proving that we could use custom properties in all our supported browsers and reliably use them across the Shadow DOM.
The implementation involved cleaning up some technical debt in our SASS/CSS and then a significant chore of creating all the CSS Custom Properties. In addition, we handled the delivery in a way that isn’t a huge breaking change for teams that don’t need to theme their applications or prefer to use the SASS-based theming we support today through 3.0.
But to fully realize the benefits of the web components in Clarity Core, we have to deprecate SASS-based theming in 3.0. This means, starting in 4.0, CSS Custom Properties will be the only way to theme Clarity applications.
Move Clarity Icons to Core–3.0 release (Nov-Dec 2019)
The Clarity Icons migration is our first proving ground for the Lit-based architecture and a fundamental effort towards delivering our set of essential components.
Foundational Components–Q1 2020
Following the icons migration, we will see more foundational components entering the fray.
By “foundational components”, I mean components upon which more complex components depend. We cannot, for example, have an “icon button” without icons–or buttons.
After we complete our foundational components, we plan to move on to “strategic components” through the remainder of 2020. This phase two of component delivery will not constitute all of the components in Clarity Angular today but it will be a good number of them.
When designating something as a strategic component, we are looking for components that satisfy one of three criteria:
- Components that fill an immediate need with a component that non-Angular teams interested in using Clarity do not have access to today…
- Components that augment the Clarity Angular library with components that the library currently doesn’t have, and…
- High-value components that are not easily replicated using the HTML and CSS Clarity currently offers.
This may mean that we don’t jump right into forms. Maybe we focus on something like the datepicker. Or the wizard.
It all depends on the intersection of need, value, and availability.
Contribution Guidelines–Nov 2019
Our contribution guidelines will be released early on during our work on the “foundational components”. By nature, these components will be simpler in implementation. There will be a lot of “low hanging fruit” componentry that we will not be tackling right out of the gate as we focus on foundational components and more complex, strategic components. This makes this a fertile ground for external contributions and, if you’re looking to contribute, keep an eye out for those contribution guidelines!
React Wrappers (2019 on…)
Lastly, the foundational component work will introduce our library of “react wrappers” for Clarity Core. So keep an eye on those for a preview of how we plan to support React teams with Clarity Core.
When it comes to components geared towards building websites and web applications, we feel the future of the web is framework independence. That doesn’t mean frameworks go away.
But it does mean that component libraries that rely on a framework for their delivery will become less useful.
As one of the founders of Clarity, I can say that this team has always bet on the web. Whether it was ES2015/ES6, CSS3, SVG, or HTML5, we unanimously believed the best path forward was adopting web standards.
We have proven that the time is right for web components and we feel confident that the time is right for Clarity Core.