Releasing the new QuintoAndar brand through our design system

Fernando Rodrigues
Blog Técnico QuintoAndar
7 min readApr 1, 2022

This is an engineering view from the QuintoAndar rebranding project. We will explain how we planned, executed, and deployed a new brand in over 20 customer-facing applications with zero bugs.

In mid-2019, our design system team was created to solve a big challenge: rollout a new brand across our user journey, which happens over ~20 applications. At the end of this year, the rebranding project was discontinued but we kept the team once our first results were good for our front-end scalability and design/developer experience. Three years later, we released the new brand in our products, on native and web platforms, overnight, and I will share how we did it.

Migrating legacy UI code

Our first product was released in 2013. We started as a small startup focused on solving bureaucracy issues related to the real estate market. On our design system's day one, we already had to deal with over ~10 applications — in order to reuse front-end code in those applications, we had created a shared library with components, services, and configurations. Also, Material UI was our main library to create interfaces. To summarize, Cozy, our design system was created after years and years of our first applications.

With the idea of having more control and UI consistency, our first step was to create the basic components and migrate the legacy code to these new pieces. To do that, we started to create codemods based on jscodeshift API. These scripts read the codebase and make changes updating or removing the components' API.

An example of our codemods updating our Typography component API.
An example of our codemods updating our Typography component API.

The first ones were simple, once we kept a similar API of our legacy components. The codemods we use today are way more complex and help with more than changing the code. Automatically changing the code has stayed in our DNA and we use it heavily to make changes to how our Design System is used. The next step will be to integrate this into the CI steps to do it automatically in the applications since we still rely on someone on the teams running them for their apps.

Improving the design system coverage

An important thing in software development is to give names to things. You must know how to call the problem to solve it.

With our basic components migrated, the next step was to improve the design system coverage in our applications — we have named it Cozy Compliance. The design system’s team had defined a group of rules that help the product teams to have a diagnostic about how compliant their application is with the design system. The basic rules are:

  • How many imports the application are doing of legacy UI code?
  • How much direct usage of Material UI in the codebase?
  • How many Cozy Components are being modified with CSS override?
  • How many local components does the application have?

The data generated from the answers to these questions generated a score about each application's health.

This is a screenshot from the spreadsheet that we used to track the application’s health-related to the Cozy Compliance.
This is a screenshot from the spreadsheet that we used to track the application's health-related to the Cozy Compliance.

Another way, was to make explorative tests in our main customer-facing applications. We had opened each screen and analyze if it is compliant or not.

After the diagnosis, we defined some actions to improve the design system coverage. The first one was to create lint rules using ESLint to avoid bad usage of legacy UI code or Material UI. Another initiative was a monthly event called “Cozy Days”, where we promoted and coordinated big refactorings with product teams. In the last one, we created groups with different product team developers and designers to make the applications better with design system usage.

In the end, the last issues related to the Cozy Compliant score were huge and a burden to solve with codemods, lint rules, or refactoring initiatives. So, an important step was to create a team to work on the main user journeys with more issues. Their goal was to ensure that these journeys would have a good brand experience. Beyond solving design system issues, this team was responsible for redesigning entire experiences, as our landing page quintoandar.com.br.

Tracking and measuring our progress

An important attribute of our design system team is that we work with a product manager. In practice, it means that Cozy is treated as any other digital product. We make research, hear our customers, have a roadmap and a customer-centric point of view.

Since our early deliveries, we measure how many imports of our components are being used in our applications, the number of imports of legacy UI code, etc. So, every month we look for these numbers to help us to prioritize our energy.

To do that, we use bash script and Node.js scripts with AST to read the application’s codebases and collect data. This topic is complex and we can do another deep article about only this.

Evolving our foundations

The foundations are the first layer of a design system, like colors, typography, spacing, and borders. The Cozy's foundations were based on the Material UI theme.

Once we redesign it and the brand has distanced from the Material Design (e.g. we stop using “primary” or “secondary” terms in our palette), we decided to rethink our design tokens architecture. In addition, there were other product requirements, such as the consistency between web and native apps, better predictability of custom components created by product teams, and the flexibility to change our base brand values.

Connecting web and native foundations

We use React for web development and Flutter for the Android platform (it’s coming soon on iOS too). There are some web views through the user journey in the native platform. Consistency between mobile and web is important for us.

Style Dictionary was the tool that we choose to build our design tokens on different platforms. We define our design tokens in a JSON and generate JavaScript modules and Dart classes with the same source of truth.

Increasing the predictability of custom components

A premise of building a design system is consistency — and achieving it is hard. We wanted away to help us is to raise the predictability of what the product teams are developing for the final users. With this in mind, we created some tools for the product teams to build experiences without the design system components with our foundations.

The first step was to make our design tokens available for designers in Figma and developers through our libraries. In practice, instead of doing usage of values that don't make part of our foundations, people build custom experiences using our design tokens.

We choose the design tokens that we wanted to make available and created an architecture to provide a better experience, helping the teams avoid building experiences outside our brand guides.

Rethinking the design tokens architecture

As I said before, our first foundations were created around the Material UI theme. It's a flat object structure and every value is public. But at this point, we needed privacy for some values and a better understanding of the product teams. The idea was to prevent people of build things outside our guides.

The final result has three layers: base, alias, and component tokens.

Base tokens are the layer that has contact with the “raw” values. They are private, and the goal is to abstract different types of design foundations.

Alias tokens are the way that we found to categorize the different pieces of a UI. It's the layer that helps the teams to build custom components.

Lastly, component tokens are responsible for the consistency between different platforms. We're using these tokens to build components in Flutter and React.

The product team’s role

We're a platform team, which means the product teams continue to have autonomy on and ownership of their projects. The responsibility to bump the design system into the final application with the latest version is theirs and not ours.

Once the rebranding was a strategic bet for the company, every product team had one week to work on the design system update. Meanwhile, the design system's team was supporting and solving issues that were found in the update process. We also coordinated bug-bash sessions to evaluate our main journeys.

After this process, the product teams were responsible to solve the main issues and deliver a release and fast-forward branch with the project updated with the latest design system version.

Go live: releasing the project

With each project relying on a branch with the latest design system version, the brand tribe (which the design system's team makes part) was responsible for deploying each application.

First of all, we deploy our first application (quintoandar.com.br). After it, we had started to deploy the others.

An important step was to clean the cache of our CDN, and it works fine and quickly.

A video with our design system working in the production environment.
A gif with our design system making things happen in production.

From day to night, all the applications that our final user entered, we showed our new brand! ✨

--

--