Thinking in
Design Systems: 

Who is this article for?

It will be useful for both designers and developers, it doesn’t matter which tool you are using, all principles are the same and can be applied both with code or design tools such as Sketch or Figma 👌.

There are a lot of approaches to kicking off a design system for your web application — This article is part of a series on “design systems” and the challenges we faced with building our own. Let’s take a look at how to build a color system, and what are the best practices to make it simple and scalable.

Ok, let’s start!

The essential color palette

Primary colors

These colors displayed most frequently across your app. They can represent active states, accent elements or text-color.

Secondary colors

Secondary colors are optional, but they provide more opportunities to distinguish your product. These colors are used less often to emphasize or accent elements. Secondary and tertiary color palettes are often used in complex products.


Use the primary or secondary palette to create shades. In the theming section, I will show you how we сoped with it.

Keep your color palette as simple as possible, because it’s easy to maintain and scale your design system through the component library, also try to use shades and colors wisely for consistency and scalability.

“Simple can be harder than complex: You have to work hard to get your thinking clean to make it simple. But it’s worth it in the end because once you get there, you can move mountains.” — Steve Jobs.

Naming your colors

When it comes to naming color variables, there are two main approaches: semantic and declarative. Neither of them is wrong.

The Semantic approach works better for massive and scalable design systems, while the declarative approach is used for small independent modules.

Semantic naming — “What is it representing?”

Every component in your system has different states such as initial, active, error, success, hover, etc. Every state could be represented by different colors and this is where the naming convention would come in handy. To make it happen we applied the theming approach. For each state of the element, we used different themes represented by different colors.

                const colorPalette = {
primary: '#4040FF',
secondary: '#A640FF',
tertiary: '#FF40DC',
primaryForeground: '#333333',
secondaryForeground: '#333333',
tertiaryForeground: '#444444',
primaryBackground: '#FFFFFF',
secondaryBackground: '#FFFFFF',
tertiaryBackground: '#F3F3F3',
active: '#FFFFFF',
warning: '#FF4040'

Declarative naming — “What is it?”

You can use declarative naming for components that are used independently from the main system. It’s really easy to use and will be encapsulated from your main color palette.

                const colorPalette = {
white: '#FFFFFF',
red: '#FF4040',
black: '#000000'


Once you created your essential color palette, you can use it across the design system and set palette values to your CSS properties depending on your themes. In Rene, we are using styled-components for theming. I can assure you that these principles will work for other conventions such as CSS variables, CSS modules, etc.

Let’s take a look at the Tree-Element component:

Initial Theme

                const initialTheme = {
color: primaryForeground, // #333333
background: primaryBackground, // #FFFFFF
borderWidth: '1px',
borderStyle: 'solid',
borderColor: primary // #4040FF

Primary Theme

                const primaryTheme = {
color: active, // #FFFFFF
background: primary, // #4040FF
borderWidth: '1px',
borderStyle: 'solid',
borderColor: primary // #4040FF

As you can see we created two different themes to describe two different component states, the difference between them is only in palette values.

We also found that using objects for theme description is very convenient, and this approach can be used for describing error, success or other states of the element.

The final styled object which will be compiled into pure CSS will look like this:

                const style = {
color: theme.color,
background: theme.background,
borderWidth: theme.borderWidth,
borderStyle: theme.borderStyle,
borderColor: theme.borderColor

If you want to change the primary theme of the element to the secondary, you only need to pass specific property:

                React component -> 
                const secondaryTheme = {
color: active, // #FFFFFF
background: secondary, // #A640FF
borderWidth: '1px',
borderStyle: 'solid',
borderColor: secondary // #A640FF

As simple as that: style your components. But as I mentioned above, you should be careful with color names. For instance, if you use a declarative way to describe an active color such as white (#FFFFFF) and apply it everywhere through your themes for different components properties (e.g. borders, icons, and text-colors), you will need to change it manually everywhere once you decide to change color palette value from white(#FFFFFF) to another color.

                const secondaryTheme = {
color: white, // #FFFFFF

...other CSS declarations

Theming shades

For creating shades, we are using primary or secondary colors and changing only the alpha parameter. You can also use tertiary colors, yet remember the rule of simplicity. To make an editable state for the Tree-Element component, we used a simple color library, and you can do the same with pure CSS using an alpha parameter or using SCSS transparentize function.

Editable Theme

                // Styled Components
                const opacity = {
primaryOpacity: 0.50,
secondaryOpacity: 0.25
                const backgroundColor = color(primary)
                const editableTheme = {
background: backgroundColor
                // SCSS
$primaryOpacity: 0.5;
                .selector { 
background: transparentize($primaryForeground, $primaryOpacity);

This is how we are using colors in our design system.

We covered naming conventions, color palette, themes, and shades. Remember! Keep it simple.