Component design systems let teams collaborate to introduce a consistent user visual and functional experience across different products and applications.

On the designer's side, a predefined style guide and set of reusable master components enable consistent design and brand presented to users across all different instances (products etc) built by the organization. This is why great teams like Uber, Airbnb, Shopify and many others work so hard to build it.

On the developer's side, a reusable set of components helps to standardize front-end development across different projects, save time building new apps, reduce maintenance overhead and provide easier onboarding for new team members.

Most importantly, on the user's side, a successful component design system means less confusion, better navigation of your products, warm and fuzzy brand-familiarity feeling and better overall satisfaction and happiness. For your business, this means better results.

But, building a successful design system can be trickier than you might think. Bridging the gap between designers and developers is no simple task, both in the process of building your system as well as over time. In this post, we’ll walk-through the fundamentals of successfully building a component design system, using it across projects and products, and growing a thriving and collaborative component ecosystem within the organization, that brings everyone together. We’ll also introduce some shiny modern tools that can help you build it. Please feel free to comment below, ask anything, or share from your own experience!

Bridging the gap between design and development through components

When building your system you will face several challenges. The first, is achieving true collaboration between designers, developers and everyone else (product, marketing etc). This is hard. Designers use tools like Photoshop, Sketch etc which are built for generating “flat” visual assets that don’t translate into real code developers will use. Tools like Framer aim to bridge this gap on the designer’s side.

Developers work with Git (and GitHub) and use different languages and technologies (such as component-based frameworks: React, Vue etc) and have to translate the design into code as the source of truth of the design’s implementation. Tools like Bit turn real components written in your codebase into a visual and collaborative design system (examples), making it easy to reuse and update components across apps, and visualizing them for designers.

Modern components are the key to bridging this gap. They function as both visual UI design elements as well as encapsulated and reusable functional units that implement UX functionality that can be used and standardized across different projects in your organization’s codebase.

To bridge the gap, you’d have to let designers and other non-coding stakeholders collaborate over the source of truth, which is code. You can use Bit or similar tools to bridge this gap and build a collaborative component economy where developers can easily build, distribute and adopt components while designers and everyone else can collaborate to build and align the design implementation of components across applications.

Choosing your stack and tools

The choice of technologies and tools is a major key in the success of your design system. We’ll try to narrow it down to a few key choices you’d have to make along the way:

Framework or no framework?

Modern frameworks like React, Vue and Angular provide an environment where you can build components and build applications with components. Whether you choose a view library or a full-blown MVC, you can start building your components with a mature and extensive toolchain and community behind you. However, such frameworks might not be future proof, and can limit the reuse and standardization of components on different platforms, stacks and use-cases.

Another way to go is framework-agnostic web components. Custom components and widgets that build on the Web Component standards, will work across modern browsers, and can be used with any JavaScript library or framework that works with HTML.

This means more reuse, better stability, abstraction and standardization, less work and pretty much everything else that comes with better modularity. While many people are sitting around waiting on projects like web-assembly, in the past year we see new tools and techs rise to bring the future today.

The core concept of a standardized component system that work everywhere goes naturally well with the core concept of web components, so don’t be quick to overlook it despite the less mature ecosystem existing around it today.

Component library or no library?

Building a component library is basically a way to reduce the overhead that comes with maintaining multiple repositories for multiple components. Instead, you group multiple components into one repository and distribute it like a multi-song CD music album.

The tradeoff? App developers (component consumers) can’t use, update or modify individual components they need. They are struggling with the idea of coupling the development of their products to that of the library. Component collaboration platforms like Bit can greatly mitigate this pain, by sharing your library as a “playlist” like system of components that people can easily discover, use, update and collaborate-over across projects and teams. Every developer can share, find, use and update components right from their projects.

Most larger organization implement a library (examples) to consolidate the development of their components, consolidate all development workflows around the project and control changes. In today's ecosystem, it’s hard to scale component-based design systems without libraries mostly due to development workflows (PRs, issues, deployment etc). In the future, we might see more democratized component economies where everyone can freely share and collaborate.

When building your library you effectively build a multi-component monorepo. Open-source tools like bit-cli can help you isolate each component, automatically define all its dependencies and environments, test and build it in isolation, and share it as a standalone reusable unit. It also lets app-developers import and suggest updates to components right from their own projects, to increase the adoption of shared components.

Component discoverability and visualization

When building and distributing components you must create a way for other developers, and for non-developers collaborating with you, to discover and learn exactly which components you have, what they look like, how they behave in different states and how to use them.

If working with tools like Bit you get this out of the box, as all your components are visualized in a design system made from your actual components. Developers can use and develop components from the same place designers, marketers and product managers can view and monitor the components.

If not, you can create your own documentation portal or leverage tools like Storybook to organize the visual documentation of the components you develop in a visual way. Either way, without making components visually discoverable it will be hard to achieve true reusability and collaboration over components.

Building your design system: top-down vs. bottom-up

There are two ways to build a component design system. Choosing the right one is mostly based on who your are and what you need to achieve.

Design first, then implement reusable components

The first, mostly used by larger organizations that need to standardize UX/UI and development across multiple teams and products, is to design components first and then make sure this design is implemented as components (often building a library) and used everywhere.

A super over-simplified structure of this workflow looks like this:

Build a visual language and design components

Implement components in a git-based project in GitHub/Gitlab etc

Distribute using component-platforms like Bit and/or to package managers

Standardize instances of components across projects and apps

Collaboratively monitor, update and evolve components (using Bit or other tools)

Code first, then collect components into a design system

The second, often used by smaller and younger teams or startups, is to build-first and then collect existing components from your apps into one system, align the design, and keep going from there. This approach saves the time consumed by the design-system project, time which startups often can’t afford to spend. bit-cli introduces the ability to virtually isolate components from existing repositories, building and exporting each of them individually as a standalone reusable unit, and collect them into one visual system made of your real code. So, you can probably use it to collect your components into a system in a few hours without having to refactor, split of configure anything, which is a quick way to do it today.

This workflow looks like this:

Isolate and collect components already existing in your apps into one collection (Bit is useful)

Bring in designers and other stakeholders to learn what you have and introduce your visual language into this collection

Update components across projects to align to your new collection

Use these components to build more products and apps

Collaboratively monitor, update and evolve components (using Bit or other tools)

Design systems and atomic design

Through the comparison of components and their composition to atoms, molecules, and organisms, we can think of the design of our UI as a composition of self-containing modules put together.

Atomic Design helps you create and maintain robust design systems, allowing you to roll out higher quality, more consistent UIs faster than ever before.

Learn more in this post: Atomic Design and UI Components: Theory to Practice.

Collaboratively manage and update components

Over time your design system is a living creature that changes as the environment does. Design might changes, and so should the components. Components might change to fit new products, and so should the design. So, you must think of this process as a 2-way collaborative workflow.

Controlling components changes across projects

When a component is used in 2 or more projects, sooner or later you will have to change it. So, you should be able to update a component from one project to another, consolidate code-changes and update all dependent components impacted by the change.

If you are using Bit this is fairly easy. You can import a component into any project, make changes, and update them as a new version. Since Bit “knows” exactly which other components depend on this component in different projects, you can update all of them at once and learn that nothing breaks before updating. Since Bit extends Git, you can merge the changes across projects just like you do in a single repository. All the changes will be visually availbe to view and monitor in your shared bit.dev component collection.

If not, things become trickier, and your component infrastructure team will have to enforce updates to their libraries for all projects using these libraries, which impairs flexibility, creates friction and makes it hard to achieve true standardization through adoption. Yet, this is harder but not impossible, here is how Walmart Labs do it. You will also have to make sure that both changes to code and design are aligned in both your design tools and library docs wikis, to avoid misunderstandings and mistakes.

Grow a component ecosystem in your organization

Building a design system is really about building a growing component ecosystem in your organization. This means that managing components isn’t a one-way street; you have to include the app-builders (component consumers) in this new economy, so that the components you build will actually use them in their applications and products.

Share components that people can easily find and use. Let them collaborate and make it easy and fun to do so. Don’t force developers to install heavy libraries or dive-in too deep into your library just to make a small pull-request. Don’t make it hard for designers to learn exactly which components changes over time and make it easy for them to collaborate in the process.

Your component design system is a living and breathing organism that grows and evolves over time. If you try to enforce it on your organization, it might die. Instead, prefer legalization and democratization of components, their development and their design. Regulate this process to achieve standardization, but don’t block or impair adoption- at all costs. Bit is probably the most prominent power-tool here too, but please do share more if you know them.

Conclusion

Design systems help to create consistency in the visual and functional experience you give you users, while forming your brand across different products and applications. Modern components, with or without a framework, let you implement this system as a living set of building blocks that can and should be shared across projects to standardize and speed development.

As designers and developers use different tools, it’s critical to bring them together over a single source of truth, which is really your code since this is what your users really experience. A democratized and collaborative process between developers, designers, products, marketers and everyone else is the only way to grow a thriving and sustainable component ecosystem that breathes life into your design system.

Modern tools built for this purpose, such as Bit and others (FramerX and BuilderX are also interesting on the designer’s end) can be used to build, distribute and collaborate over components to turn your design system into a consistent and positive user experience everywhere, and to manage and collaborate over components across teams within the organization.

Thanks for reading!