Pull to refresh
We help the businesses with digital transformation

Main Challenges and Mistakes in Creating Your Design System

Иннотех corporate blog Development of mobile applications *Mobile applications design *
Original author: ton252

Much has been written about what a design system is and how it should work. Yet, much too often the authors cover only a certain aspect of this broad subject. In my turn, I would like to review the very process of creating a design system based on the experience of our team, talk about the main challenges we have encountered and, perhaps, caution against the common mistakes we have made in this rocky journey. Whether to follow it is up to you.

Okay, let’s get right into it...

A bit of theory

What is a design system? According to Wikipedia, a design system is a set of components, rules, guidelines and tools that help develop products with better quality and faster. That’s really nothing up for debate here.

I would roughly divide the design system into two parts:

  • Visual presentation (for designers);

  • Technical implementation (for developers).

Visual presentation is a set of components, fonts, icons, colour schemes, etc. in, say, Figma or Sketch. This part is developed and used by designers to quickly put together and build the interface.

Technical implementation is a mirror image of the visual presentation for developers, in which comes as code. Unlike the visual presentation, which must exist in a single instance, there can be many technical implementations that vary by platforms (iOS, Android, Web) or specific frameworks (iOS: UIKit and SwiftUI; Android: XML/Layout and Compose, Web: Angular and React).

Additionally, I would divide design systems into two further categories:

  • Local;

  • Global.

Use of local and global design systems
Use of local and global design systems

Local design systems are systems that were developed for and work only on one company product. This approach is implemented in most projects.

Global design systems, in concept, are not all that different from local systems, except they are created for a group of products, and this, in turn, imposes a number of additional requirements and constraints on them.

A local design system can be simply developed as part of a product at no additional cost (you just put all your components together in one place, combine the common components and align them with your overall corporate style and guidelines). But either way, the local design system appears in any project because designers and developers want to be able to re-use components, rather than create new ones from scratch every time. But if you still want to take a shot at a global design system, it should itself be a complete product and you must be willing to dedicate most of the team’s time to it. The consumer of the product will be a very sophisticated audience of developers and designers.

If your goal is to boost product awareness, local design systems that are united by common guidelines will be just enough to fit your bill. Just take a look at Yandex products: when you open Yandex.Go or Yandex.Food apps, they appear similar, even though they are two independent teams, with different local design systems united by a single style. (It may have changed by now, though).

Great, let's move on then.

Study the task

My team was tasked with creating visual presentation and technical implementation of the design system for a large customer. Fifteen million users were to become end consumers of the design system. It was assumed that the entire organisation would be using the design system, not just one or two teams.

Analyse your audience

As we remember, our design system is an independent product. So what should we do when we start developing a product? Does it mean you have to immediately begin to design components and write code? Not at all! You have to analyse your audience to understand the needs of other teams. We carried out a number of surveys.

Survey No 1 For designers

  • What tools they use;

  • What approaches to building the design they use;

  • Number of designers in a team.

We haven’t found anything new here. All designers used Figma, and their approaches to design were roughly the same. But we discovered an interesting thing: the company has already been using several local design systems that function within the product group, but they are in no way connected.

The task facing the designers was quite clear: to choose the most common design system and improve it such that it factors in the needs of all other teams. Naturally, when you join a project, you want to throw everything out the window and start with a clean slate. This way seems to be much faster and more correct, but in practice, it’s much faster to improve or perhaps tweak the old one than to develop something new from scratch.

Survey No 2 For developers

  • The minimum supported version of the operating system;

  • Which technology stack is used;

  • Number of developers in a team.

After the survey, we got a fairly common picture. The minimum versions of operating systems most teams had were iOS 11 and Android 5.0, with the standard technology stack of UIK it for iOS and Layout + XML for Android.

Results of technology stack surveys in our company
Results of technology stack surveys in our company

We are looking at the technical aspect of the design system for a mobile app. For a web version, it’s roughly the same story.

Everything seems to be ready, data have been collected, teams have been interviewed and so we can get down to business, but we have overlooked a very important aspect, which will be discussed further.

Don’t try to outsmart your users

Our team gathered statistics, factored in all the requirements and suggestions and developed the first version of the library. But we didn’t think we would face serious resistance from many other teams that were working on products with a fairly long lifecycle.

Were the teams to blame since they didn’t want to switch to a new design system? Absolutely not! Just imagine: people you don’t know approach your team and say that designers need to use only new components in the design, and developers need to completely rewrite the code connected with the UI and then perform regression testing. I don’t know who would have answered differently in their shoes.

What does that mean? It means we initially chose the wrong target audience. As we know, a design system should speed up product development, and not slow it down. And for teams that have long been working on the product, the innovation offered would bring nothing but a huge backlog. So, the easiest thing we could do was take another route and find young teams, especially those just emerging, that did not have a full design and didn’t start development yet, or it was in the earliest stage.

Results of technology stack surveys in young projects
Results of technology stack surveys in young projects

We had to refine the survey and collect the stats over again. This time, with a different outcome. We were lucky in case of Google’s OS because the Android community uses mostly conservative approaches to layout: Layout + XML. However, when it came to iOS, new teams headed over to SwiftUI and they found it important for transitioning to a new library.

Fortunately, we had enough competence, and the team quickly released a new version for SwiftUI. The downside, though, is that we still have to maintain two versions of the library: SwiftUI and UIKit. But that’s twice as much work.

To maintain the community’s loyalty, we don’t stop supporting UIKit, although we are mostly developing new features for SwiftUI.

Implement the design system in small steps

Once the survey is completed and the basic functionality of the library is implemented, it’s time to integrate it into other products. For good or ill, our team did not have its own product that we could use to test the library in full.

So, we decided to look for young teams who were about to start the development of a new product and didn’t have time to develop their own design system. Crucially, they had to be loyal to bugs and flaws in the library.

One would think finding such teams is a tall order. But you need to figure out what you can offer in return. We had a deal: the guys used the library, reported bugs and flaws in the library, while we added their tasks to the backlog as high-priority tasks and promptly released hotfixes to resolve critical bugs.

A quick tip: start testing the library as soon as possible to get feedback from users earlier. It’s better to move in small steps and get regular feedback than to take half a year to do something, only to realise that no one wants the final result.

Start a feedback system

Once we started working on the design system as a product that other people would use, we realised that we needed to collect feedback and show the progress of the work.

We started out with a simple chat on Telegram, where we posted news about releases, discussed problems and so on (don’t be too harsh on us, we had to move on quickly to collect feedback). But later we realised that a lot of requests from users didn’t reach us amid growing discontent.

We solved this problem by letting all teams view our Jira board. And we also added shortcuts to enter tasks for bugs and improvements.

In addition, we introduced a duty system. A developer on duty is responsible for collecting feedback on bugs. If the bugs are critical, the developer will either fix them or appoint a responsible person and release a hotfix with corrections later. The person on duty also answers questions about working with the library.

If you use Atlassian products, it makes sense to use Jira Service Desk, a service for organising customer support. It’s handy for developing request forms with automatic task creation in Jira.

Project issue tracker on GitHub
Project issue tracker on GitHub

At the time of publishing, we have already coordinated all the details with the security team and released the library to the public. That’s why the technology stack has changed a little: we use Github Projects + Issues, and all library-related communication and flooding remained on the Telegram channel.

Design and code syncing

After the first teams began using our library, we faced a barrage of questions about the status of component readiness, what frameworks components work with, or about the name of the class in the code that corresponds to the component.

And here we come to one of the most relevant issues you’re sure to be dealing with: design and code synchronisation.

The design process always starts just before the development. The conundrum here is how to give designers access to new components as early as possible, while still showing the users that the component is not yet ready in the code.

We introduced a set of rules:

  • Changes in the design in existing components are not published until the appropriate improvements are made in the code;

  • The design system shows the status of the component readiness: not implemented / in development / ready;

  • Design and development are synced twice per sprint.

At the earliest stages, there were some problems when the designer added new components to the design system or slightly changed the old ones without telling the developer about it. Consequently, the users suffered as they could not find the necessary component in the design system: it was available in the design, but not in the code.

Initially, our rule was very simple: a designer cannot change the ready components in the code, and if the components are changed, they are not published until a developer makes changes to the library. If, while working on the design, there is a need to improve the component, first, the task for improvement has to be set in the code, and until it is implemented, the previous stable version of the component is used.

It is important to remember to show the status of the component readiness, the name of the class in the code and the framework in which it is available.

P. S. Too bad that Figma doesn’t offer developers a normal versioning support or a system similar to Git. Don’t rush to write comments that such a system exists: it kind of does, but no design team has yet shown how it could be conveniently used.

Component structure
Component structure

Do not delay automation of processes

At the earliest stages, when we just started work on the design system, we only had automatic test runs and library deployment configured.

But at some point, the development seemed to go very slow. It was odd because there were no extra tasks we had to work on. We looked into this situation and realised that routine workflows, such as updating icon packs, or syncing colour palettes, take up a ton of time. To put it in context: the library now has about 200 icons, 20 fonts and three themes of 30 colours.

Now let’s do some math. The developer spends an average of one to five minutes on icon updating and up to half an hour if test runs have to be performed. Moreover, normally, it's not just a couple of icons that need to be updated, and you're getting an interesting picture. Our developers could easily spend two or three hours a week syncing the design and code.

Imagine that while developing the design system, the designer is constantly updating all these resources, and then the developers have to manually upload them and check if everything has been uploaded correctly. It’s not rocket science to figure out that it takes about a minute to add an icon: upload, add and check. This is beyond the pale for a team with a sole focus on the design system.

The guys and I did some thinking, analysed the solutions offered by teams from other IT companies and created a plugin to upload icons, convert them to Vector in Android and generate xcassets in Xcode. Now the entire icon pack is uploaded at once and automatically converted to the required format.

Resource updating script workflow
Resource updating script workflow

With themes and colours, the workflow is more interesting: we used Figma API to upload components. Since Figma’s API is not the most convenient, we had to do a lot of requests and patching. In the end, we got a JSON object with all the data on the theme. Using the liquid template language, it allows you to generate .swift/.kt files with the app’s themes.

By automating the processes, we significantly reduced the time for synchronisation and adding / updating new themes and resources.

You don’t have to write your own tools for resources' uploading or code generation. We wrote those scripts on our own because our situation was rather specific and ready-made solutions didn’t work for us. At the earliest stages, I would recommend using ready-made tools with an open source code. I know for sure RedMadRobot and HeadHunter guys have them on GitHub.

Open for extension but closed for modification

As soon as we started working on the tool that other people were using, we received a ton of ideas and suggestions for improvement. And the most frequent request was to “add this component to the design system, and this one, and that one...”.

Needless to say, developers are pursuing commercial interests and just want to dump support and development of the component on you. And here it’s important to strike a balance and see the whole picture: you’re creating a system that will be used by more than one team. So do not add product-specific components to the design system as this will complicate support and draw flak from other teams who do not need the component. On the other hand, if most teams are really going to use the component, make sure to include it.

If we added all the components that other teams ask us to add, our design system would turn into a dumpster that no one would want to have to deal with in their project.

As we remember, the design system is intended to help and guide, and never limit creative freedom of people who develop the product based on it. So, we used one of the SOLID principles: 'open for extension but closed for modification'. Developers and designers can modify and combine our components, thereby creating their own unique design without breaching the basic principles of the global system design or turning it into a dumpster.

Understanding the following rules will help you. Design systems are composed of atoms and molecules. Atoms are invariant elements that can’t be broken down any further and that make up more complex elements: molecules. It would be much easier if the system you were developing was composed more of atoms. So, it is better to make a lot of small components and combine them to create a design, rather than make one large and unwieldy component and then modify it to meet the needs of all teams.

Difference between 'simple' and 'complex' components
Difference between 'simple' and 'complex' components

Striking a balance between functionality and versatility is always very tricky. You have to consider each case individually.

Break the library down to modules

After products using our library had several releases in production, more and more teams slowly began requesting us to reduce the weight of the library or speed up the build process.

It’s no secret that the size is one of the important factors that boosts the conversion of app downloads.

First off, we reduced the size of resources. However, that was not enough, and we moved on. In the iOS project, we had both SwiftUI and UIKit components, but why would developers need both of them in one project at once? It would make more sense if the team chose which module to connect. The takeaway here is that dividing into modules is necessary.

We came up with the following division scheme:

  • Resource module Stores all resources, images, fonts;

  • Theme module Stores colour themes and an update mechanism;

  • Component module SwiftUI;

  • Component module UIKit.

Design system modules
Design system modules

If the team needs only fonts and icons, it connects the resource module. If they only need theming, they connect the theme module. And if they need components, they choose the framework for which components are needed, and connect SwiftUI or UIKit, respectively.

You could go further and isolate each component in a separate module, but I reckon it is over the top.

Also, modularity will increase the speed of the project build. You can even pack some parts into XCFramework in advance and cache on CI.

We had an interesting case with iOS, but, unfortunately, we couldn’t do anything about it. Xcode 12/13 takes a long time to process SF Symbols, and that is why we have more than 200 of them in our library. No settings or flags were of any help. We solved this problem by uploading a binary version of the library – SPM supports this feature. (Thus, you don’t need to rebuild the library each time as it is already compiled.)

Work out the theming mechanism

Personally, I can talk a lot about theming, which is what I was actually doing with my team.

Theming is one of the biggest headaches every team working on the design system faces. In the previous step, we put it in a separate module.

A theme is not just about the colours. It can also include resources.

Our theme model is composed of the following set:

  • Colour palette: a set of colours used in a theme;

  • Font palette: a set of fonts used in a theme;

  • Resources: a set of specific resources that can change depending on a theme.

In fact, a theme may have a much wider range of settings; for example, you can include filleting and even audio signals.

The most challenging thing we have faced was syncing the naming of colour and font tokens. That’s a huge problem for projects with a long lifecycle. At the same time, the colour theme should be open for extension. Designers should be able to add new colour tokens, thereby increasing the number of custom colours.

Fixing just one colour / font scheme will simply doom the design system. Very often designers and developers will need new colours and fonts specifically for their product.

Possibility of extending the design system
Possibility of extending the design system

A good solution would be to extend your theme with new colours and fonts, or better yet, to manually set the colours and fonts of components without having to use theming. This will increase the development time a bit, while greatly improving the flexibility of the design system.

There was a team that turned down the theming system we had offered and wrote their own schemes.

Work fully with an example project

If you have a design system as a separate module on your project, you will almost certainly have a Sandbox (example project) where you test your components before taking them straight to the main project. Often, it is simply a dumpster where the linter isn’t even set up. And why would you even keep track of this project if it doesn’t go into production?

We have our own example project, but we went a step further and decided to make it useful not only for developers but for designers, testers and users of our library as well.

I said earlier that our design system didn’t have its own product which we would use to test the behaviour of components, so the example project has become such product.

For us, this app has become not just a showcase with components, but a full-bore interaction tool for developers, designers and testers.

During the development, we tried to make the example project easy to implement. You don't want to make it too complicated and focus on functionality or development speed.

We identified a number of functions an example project should implement:

  • Display the work of components of the design system in all states – you need it to write tests and conduct design reviews.

  • The code shows developers how to use certain components correctly. In addition to reading the documentation, it is sometimes handy to open a screen in the app and see how a component works or how a certain function is implemented in the code.

  • The possibility to edit colours and create new themes. This feature didn’t appear right away, but our designers needed to check how a particular colour would look directly on the device and test this perception on the user. Figma has a Mirror function that helps display a layout on a real device; this is very handy for designers, but if you’re going to test on a focus group, this method won’t quite work.

Live editing of the component
Live editing of the component

As a result, we have created a tool which can be used for showing, testing and improving the design system.

Unfortunately, we also don’t have enough time for everything, but we would like to add a function of dynamic population of the screen with data from JSON (a kind of Backend Driven UI for testing) as the next step in the app improvement. Thus, the tester would be able write a test case in the JSON format per component with all extreme cases where the component may break. These data would be populated, and the tests would run automatically or manually.

Build your library community

It’s important to win allies who will be carrying the design system further into projects, answering simple questions from colleagues and helping with feedback. Hold internal training events, meet at informal gatherings and just love the product you’re creating.

Instead of a conclusion

I actually started writing this article a long time ago. Today, I think that creating a single global design system looks more like searching for El Dorado or the holy grail. Everyone is looking for it, but very few could find it. And the main question is whether you really need it so much that you are ready to spend so many resources or whether it’s just a craze and a whim.

In my opinion, in most cases, a single system of guidelines and corporate colours would be just enough. You should think of a global design system only if you really have many similar products with a lot of reusable components. Ideally, they should be still at the planning stage or at the earliest stages of development. Or, if you really need to release MVP projects or White Label apps quickly and cost-effectively.

In all other cases, my tip is to keep to a local system with a set of guidelines.

Creating and implementing a design system is a complex and painstaking process. I hope I’ve covered all major aspects and bottlenecks. Reaching the logical end, you can significantly facilitate the work of your colleagues and boost product awareness among your target audience. But always think whether it is worth it or you can get by with few losses.

Links to our libraries from the examples above (Android/iOS)

Total votes 3: ↑3 and ↓0 +3
Views 814
Comments 0
Comments Leave a comment



5,001–10,000 employees