Decibel: Acast’s design system

Acast Tech Blog
Dec 11, 2019 · 9 min read

By Antoine Lehurt

Logo: Decibel — Acast’s Design System
Logo: Decibel — Acast’s Design System

As a company grows, so does the number of different products. This introduces a level of fragmentation in both the overall user experience and in visual consistency.

UI components, libraries, guidelines and documentation are usually classed as a ‘nice to have’, aside from the quarter and sprint goals. And, without clear ownership, principles for what works best are kept within teams and might not be communicated to others in the organization who could also draw benefits from it.

We want teams to be able to focus on solving specific problems, and to increase their speed of iteration, without needing to spend time building the same components over and over again. Instead, they should have a library where UI details and accessibility have already been figured out.

Listeners, podcasters, publishers and advertisers use different Acast products owned by different teams, but it’s essential we give them a consistent experience and visual elements.

Our design system, Decibel, is our answer.

“A design system is a collection of reusable components, guided by clear standards, that can be assembled together to build any number of applications.”

https://www.invisionapp.com/inside-design/guide-to-design-systems/

This article focuses on the component library of our design system, including how we work with it and the tools we use.

Why build our own instead of using an existing one?

There are numerous open-source component libraries. To help us decide what would work for us, started with our most important requirements:

  • It needed to reflect our branding, and ours alone. We don’t want to couple our visual identity to another company. We didn’t want to use Material Design, for instance. Its guideline principles have valuable information about interface practices and how to think about motion design, but it’s Google’s design language.

But, throughout our research, we didn’t find the perfect match. The two main reasons for this were the lack of theming and accessibility support, so we decided to invest in building our own.

Interestingly, Reach UI has since been released, which could have been a good foundation for us as it focuses on accessibility.

Open source, but in-house

While it differs from company to company, the most common workflows are:

  • Centralized: one team owns the design system and builds everything for the “feature” teams.

We decided to follow the latter — we want gardeners, not gatekeepers. Everyone should have a sense of ownership and feel that they can easily contribute to the component library.

Since more people are involved, it helps to share knowledge around the organization for the type of components that are available or needed, and about front-end and accessibility practices.

Communication

Acast is a remote-first company so, for Decibel, most of our communication happens in GitHub. We mainly use this for project management, requests for new components to the design team, and requests for feedback on APIs.

However, once a week, we have a meeting with the front-end group to discuss all things Decibel. It’s a great forum to give feedback, request help, or discuss issues, and has helped us speed up decision making.

Contribution guidelines

As for open-source projects, we have contribution guidelines accessible in the repository, to give as much information as possible to help new contributors — and to make sure we keep a consistent codebase. It covers:

  • Expectations around code convention, testing, code quality, accessibility, and so on

Our contribution guide isn’t set in stone, however. We keep it updated based on discussions that inevitably arise during pull request reviews.

Tech stack

React

React is a component-based library maintained by Facebook. One of its strengths is that it allows us to build a hierarchy of components by composing different blocks together — so we can follow the Atomic design methodology when creating new parts.

It’s widely used in the front-end community and used in all projects at Acast, so its inclusion was a no-brainer.

Styling

With Decibel, we wanted to build component-oriented styles where we expose all building blocks as React components. We think CSS-in-JS solutions are the right approach for this type of goal, and provide several benefits out of the box:

  • We can ‘tree-shake’ styled components and only include those that are used, which optimizes the bundle size

These points are achievable with other solutions, like Sass and BEM.

We wanted to automate as much as possible to reduce time spent on pull request reviews, and to simplify the developer workflow. Therefore, we needed to bring more tools to our stack — for instance a CSS linter to make sure developers follow the BEM convention. But that would require more configuration and more maintenance in the long term.

We evaluated different CSS-in-JS libraries, and Linaria looked promising. Its main benefit was that it didn’t have a runtime, so we could let each team decide what solution they wanted to use for styling in their projects. Unfortunately, when we tried it, we had performance issues while developing components with dynamic styling.

We chose to use Styled Components, as most teams at Acast had started to use it. It has good community support, is part of the fastest engine in benchmarks and has great support for theming. We coupled it with Styled System, which helps us to stay consistent between components’ API for including style props.

Playground

While developing and maintaining components, it’s essential to test them quickly and easily in browsers. Storybook is an excellent tool for this, allowing us to test components in isolation, for different states, and to interact with them.

Storybook page of the Combobox component
Storybook page of the Combobox component

Documentation

Documentation is vital to ease adoption, but it gets easily forgotten or out of sync, so it’s essential to keep the documentation close to the code.

We chose to use Docz because it doesn’t rely on the file structure to generate the website. We can collocate the documentation file next to the component, so the component’s folder will contain everything related to it.

For instance, we can find the component, the story (for Storybook mentioned above), tests and the documentation (.mdx) in the Button folder.

Button
├── Button.js
├── Button.stories.js
├── Button.test.js
└── button.mdx

As you might have noticed, it supports MDX, which is a must-have when working with React. It allows developers to mix Markdown, JavaScript, and JSX code in the same file — so we can import the components and render it directly in the documentation.

The consumer will see how the component looks and interact with it. And all of that with zero configuration.

The only downside with Docz is that we often end up copying code from Storybook to the documentation — but Storybook had now added better support for documentation, so we’re planning to migrate to it. The documentation would only focus on the guidelines for using the component, and the playground to interact with it.

Documentation of the variant prop from the Button component
Documentation of the variant prop from the Button component

Testing

At Acast, we like to work with React Testing Library. We believe tests should cover whatever users interact with. RTL also helps developers focus on accessibility while writing tests using DOM utils for targeting elements (`getByRole`, `getByAltText`, and so on).

Snapshot testing is convenient to keep the assertion short with only one line of code (`expect(wrapper).toMatchSnapshot()`). But we don’t use them for testing React components. In our experience, snapshot testing a component doesn’t help us with catching bugs or regression.

Having a test that breaks because of HTML structure change brings more noise to the developer than valuable input — and it can bring a false sense of confidence that our components are tested.

Bundling

Decibel is used by all teams on different projects. The bundle must be ‘tree shakable’, so unused components can be removed from the consumer bundle during their building process.

Since Storybook handles the build while developing components, we only need to take care of the build process in the CI when merging on the master branch. Then we can directly use Babel for bundling.

The configuration is rather simple for our use case, and we don’t need to introduce another bundler. Here’s an example of our babel.config.js for the production build:

module.exports = () => {
const presets = [
'@babel/preset-react',
['@babel/preset-env', { corejs: 3, useBuiltIns: 'usage', modules: false }],
];
const plugins = [
['@babel/plugin-transform-runtime', { useESModules: true }]
];
return {
presets,
plugins,
};
};

Then, in the package.json, we have a task executed by the CI:

"scripts": {
"build": "rimraf dist && yarn build:es",
"build:es": "babel src --out-dir dist/es --ignore '**/*.test.js','**/*.stories.js'','**/__snapshots__/**','**/__mocks__/**'"
}

Automation

We aim to automate as much as possible within our processes, to ease contribution and reduce human error.

We use Hygen for code generation for creating new components:

It’s one of many code generators available in the open-source community. We chose it because it’s easy to implement, and it simplifies the component creation process. So far, we only use it for creating the file structure and default boilerplate when we need to create a new component.

We publish a new version automatically when we merge on the master branch:

As for other projects at Acast, we use CI/CD in Decibel. We follow the GitHub Flow for our branching strategy because we want to release a new version as soon as a pull request is approved. To feel confident in this workflow, we run the test suite and linters (ESLint and Commitlint) on the pull request before the developer can merge it.

To simplify version management, we use Semantic Release.

Based on the commit message, and following conventional commit format, Semantic Release automatically determines the version number it needs to bump (major, minor, patch). It also takes care to generate a changelog, which is useful in keeping track of changes.

We use Renovate to update our dependencies automatically:

It’s important to keep dependencies up to date, to benefit from vulnerabilities fixes and other improvements. It can be time-consuming to manage that ourselves, but tools like Renovate do it for us. We limit the pull request creation from Renovate to once a week, to reduce the noise and time we spend on reviewing pull requests.

{
"extends": ["config:base", ":preserveSemverRanges", "group:allNonMajor"],
"lockFileMaintenance": true,
"schedule": ["every weekend"]
}

Next steps

We’re on the right track, but Decibel is still in its infancy.

We’ve built a vast range of components that allow developers to build projects using only our component library. And, in the future, we want to conduct user testing and start to iterate on our building blocks.

We also need to invest more time and resources in establishing a comprehensive system and guidelines to help teams take UX decisions while using Decibel.

acast-tech

Acast is dedicated to solving the problems that face the…

Acast Tech Blog

Written by

acast-tech

Acast is dedicated to solving the problems that face the podcast industry as a whole and this blog is where we share our learnings with the community. As the industry continues to grow, it is more important than ever to work towards democratizing audio through technology.

Acast Tech Blog

Written by

acast-tech

Acast is dedicated to solving the problems that face the podcast industry as a whole and this blog is where we share our learnings with the community. As the industry continues to grow, it is more important than ever to work towards democratizing audio through technology.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store