The complete guide about design systems: Engineering

Gustavo Ribeiro
Jun 26, 2020 · 5 min read

1 of 2 of the series: the complete guide about design systems

Engineering | Walkthrough

After experiences in different projects and of different sizes, I intend to show in this series my main learnings as a developer in design systems projects from Engineering, Design, and Management aspects, in this blog post, I will cover the main aspects from an engineering perspective and build an entire design system from scratch.

Although Design Systems is a relatively new subject, in software development it is already a very old subject. In the past, when open source was a “world not yet explored”, companies and developers that worked with enterprise systems created their libraries to share code between projects, such as ORMs, queue managers, enterprise communication bus, etc. Also, frontend developers already built their “own design systems” a long time ago. The design system, as seen today, is the expression of all this in a unique language shared between design and development.

After a long time of popularizing this practice, it was observed that design systems were much more than a “design trend”, but came to show something that happened over a long time and has grown a lot in recent times: the communication gap between designers and developers.

The first thing that helps us a lot in this type of project is to recognize what’s the big picture, what will be the next step, what’s the limitation of the client infrastructure for security (approval for the usage of new services for example), how many projects are affected by this design system etc.

For this, we use a technique called mind maps, and that helps us to recognize what will be the challenges, what’s its potential and to determine people who will be focused on finishing a certain type of activity.

Mindmeister sample for design systems

Migrate your mental model

Generally, people who come from “common projects” are on the left side of this picture above. You are responsible for a project that provides user interfaces, and when you need to ship a new feature you don’t care much about versioning. Generally, you have a project that has dependencies and now your project is the dependency.

And, in this migration path, you are not used to worrying about certain items that we need to be aware of when we develop a design system, such as package management, package deployment, standardization of commit messages for generating many versions of packages, tags, and versions in SCM, changelogs and massive Documentation-Driven Development.

Imagine that you fell asleep, woke up, and are part of the Angular core team and need to push a bugfix in production; feels scary, no? haha. Thinking that way, we need to know the good practices used by these teams on a day-to-day basis and bring this to our reality.

Mono package or multi package

One of the hardest decisions at the beginning of your project will be this. The idea behind it is to serve a single package or many packages for projects.

The ideal solution is to serve multi-packages by one single monorepo and to do this I recommend using Lerna. This tool will manage all the monorepo structure, also has great documentation and provides two commands that will make your job much easier: Lerna Publish and Lerna Version

Semantic versioning all the way up!

You can read more about semver here, but, in summary, semantic versioning is a way to manage package versions in a way to tell the clients (projects) which type of features, bug fixes, or breaking changes they are getting by updating the package.

Okay, that’s cool but all that process had to be manual?

To solve this, big repositories like Angular use a standard called conventional commits which I will explain further in the topic below.

Conventional Commits

As specified on the official website, the conventional commit is a specification for adding human and machine-readable meaning to commit messages.

A sample last commit messages at Angular repository.

In summary, the commit message has a template like this

<type>[optional scope]: <description>[optional body][optional footer]

The types available help you to automatically define the next version of your package

  • major: breaking change
  • minor: feat
  • patch: build, chore, ci, fix, improvement, perf, refactor, style, revert, test, docs

Testing your packages out of the box

Before publishing your first component in production, it is interesting to be able to test it in a local proxy to check items such as bundle size, files inserted in the package, and compatibility with real projects.

The tool that can help you with this is Verdaccio. It creates a local npm proxy and enables you to publish packages in this repository, even before uploading them to your public or private definitive npm repository.


These are the main aspects of the engineering area that you need to worry about before uploading your first design system, and also I have good news!

I have compiled all these good practices in a single boilerplate that provides a monorepo structure for your design system for Angular web apps and design tokens. In the next post, I will detail each tool used in this repository and walk through the project step by step.

The repository is here: (the same boilerplate using React is a work in progress)

The packages are in this organization here:

You can check the Storybook and Compodoc generated by Netlify in this link.

Special thanks to Ivam Luz and Marcelo Costa for reviewing it!


CI&T combines strategy, design and engineering expertise…


CI&T combines strategy, design and engineering expertise, working cross-functionally to deliver lasting impact to our clients.

Gustavo Ribeiro

Written by

Passionate developer, open source enthusiast and currently working as a software engineer at @ciandt


CI&T combines strategy, design and engineering expertise, working cross-functionally to deliver lasting impact to our clients.