Satellite Design System
Creating a scalable design system to empower developers at Algolia.
- Name
- Kevin Østerkilde
- @kosai106
8 min. read

Introduction
When I switched to the Dashboard team at Algolia in 2020, we had already begun working on building out our product design system, and most of the teams contributing to the Dashboard had begun using it. My initial role was to help add new components to the system, and to help the team maintain it. Over the next two years, I'v gone from a maintainer to being the lead developer on the design system.
Over the years, we had progressed from having a small library of components to having a fully fledged design system, including more complex components and layouts, and additional tooling. I'll be going over some of these here, as well as talking a bit about our thinking behind.
Technical
Code | CI/CD | Testing | Documentation | Design |
---|---|---|---|---|
React | CircleCI | Jest | Markdown | Figma |
TypeScript | Testing Library | Next.js | Feather icons | |
Tailwind | Chromatic | Storybook |
Architecture
Our codebase was fairly simple. It was a monorepo which we manage using Yarn workspaces. We only had a few packages in the repo, the main one of course being where we keep the design system files, another for our documentation site, and some others for tools and such.
We kept the components located within each of their own folder, with their associated files being namespaced based on what they do. So for example, our Storybook files were namespaced *.stories.tsx
, Tailwind files were namespaced *.tailwind.js
and our components were just namespaced *.tsx
etc.
Here's an example of what I mean:
Root
└── src/
├── Badge/
├── Button/
├── Checkbox/
├── Dropdown/
│ ├── components/
│ │ ├── DropdownTitle.tsx
│ │ ├── DropdownRadioItem.tsx
│ │ └── index.ts
│ ├── Dropdown.tsx
│ ├── Dropdown.stories.tsx
│ ├── Dropdown.tailwind.js
│ ├── Dropdown.test.tsx
│ └── index.ts
├── utils/
└── index.ts
We used a few different technologies, but the majority of our code was written in TypeScript and React.
Our components were tested using Jest where it made sense, and all of them had visual regression tests using Storybook and Chromatic, the latter which we were early adopters of.
Accessibility
Accessibility was one of our big focuses prior to my departure. Of course, we had made sure to have some semblance of A11Y compliance since the beginning, but not to the full extend that we could have had. None of us working on the system were A11Y experts by any means but we learned as we went along, and with the focus on getting to at least a WCAG 2 compliance, we focused more than ever on improving in this area.
We made use of the accessibility plugin in Storybook to ensure that our components were passing the basics and somewhat automated this to generate reports for us on each release, which ensured we didn't introduce regressions.
Processes
We used Husky, Lint-staged and Prettier to ensure our files were linted and formatted correctly before we commit any changes to the repo. We also used Conventional Commits to ensure that our commits were consistent in order to auto generate a changelog file for our releases. Lastly, we had a small handful of Bash and Node scripts which helped us with mundane tasks, such as creating a new release for NPM.

Complimentary packages
Like I mentioned earlier, the project resides in a monorepo in which we have a few other packages than just the design system iteself:
ESLint plugin
We built a custom ESLint plugin, which helped us detect invalid CSS class names being used in our components. Basically it would yell at us if we tried to use a class name that was not defined in our Tailwind config. One way we achieved this was by in addition to the ESLint rule, to create a prefixed classname helper function.
In our case, because our design system was named Satellite, we've aptly named this function our stl
helper.
<div className={stl`bg-red-500 text-white p-4`} />
<div className={stl`flex flex-col`} />
const isActive = false;
<div className={stl`flex ${isActive && 'text-blue-500'}`} />
As you can see, it did a few things for us; Mainly it automatically adds the stl-
prefix to each class so we wouldn't have to do so manually for every class, of which a component could habe many. However it also stripped out whitespace and removed falsy values from the output - Something which React doesn't do by default.
Usage analytics
Lastly I wrote a package for gathering analytics regarding the usage of our design system across the organization. It looked through all of the Algolia GitHub Organization repositories and found all the projects that were using the design system. Then it pulled these repositories down locally in order to analyse the files and generate usage data metrics for our components, their props etc.
We didn't go too deep into this topic while I was still at Algolia, however we did capture useful metrics such as:
- Which projects were using our design system- Knowing which projects were using our design system allowed us to reach out to better understand how it was being used - This would in turn allow us to better cater to the needs of different teams
- Number of instances of a given component within each project- If a number of instances were low it could mean that the component wasn't discoverable or documented well enough - Alternatively it could also indicate that there was no need for it and that we would likely be able to deprecate it
- Number of instances of each prop for a given component- Same as before, if the number of instances were low, it could be indicative of a documentation issue - It could also simply be that we no longer had a need for the prop, and so we could start deprecating it - We used this metric when migrating older versions of our design system in some projects to great effect
I created a Storybook plugin for us to have a place to easily parse and view this data rather than looking at the raw JSON.
Documentation

This section is no longer accurate as the custom Satellite documentation has been sunset in favour of Zeroheight.
Our documentation was a custom built website using Next.js, Tailwind and MDX. Before this, our only form of documentation was our Storybook but we quickly realised this wasn't great for a couple of reasons:
Discoverability
"I didn't know that component already existed" was a common phrase we heard in the team. Storybook does have a basic search but it's not helpful if you don't know the name of a component in the first place. Moving to a custom solution means that we could make use of DocSearch by Algolia, in which we could adequately tag our components and overall just have a far superior search experience.
Maintainability
Our documentation lived together with the component as comments on the types or as a JSDoc comment above the component itself. This would in theory make it easy to update the documentation whenever the component changes but in reality this wasn't really true, so decoupling the docs instead made our component files slimmer.
Presentation
Storybook Docs offer limited amounts of customisation in how we want our documentation and components to be presented. It's possible to overwrite some styles and such, but it would never become something truly "ours" regardless of what we would do.
We considered other tools before jumping into building something from scratch but ultimately they all came with more downsides than the time investment it took to do it ourselves.
Fortunately, we were using Storybook Docs before, which uses Markdown, so it made it straightforward for us to choose to go with MDX for our docs. This way we get the power of Markdown combined with custom React components for extra ✨ flair ✨, which we make good use of to make our pages more interactive.
Final words
Working on the design system was a fantastic experience in which I learned a lot and got to make an impact on a lot of products across Algolia. We were fortunate that adoption from other teams came quickly and they've even been open to contributing on occasion.
Satellite is not public, otherwise I would have linked to the repository so you could take a look at the work we had done. We spoke about making it public but I do not know if that is still the case but if it happens I will of course update this article accordingly.
Vincent Lemeunier and Clément Aupiais whom I worked closely with on Satellite over the years! Couldn't have done it without you. 💙