[

MENU

+

]

A arquitetura por trás de um design system

Um design system não é uma biblioteca de componentes. É uma arquitetura para transformar decisões de design em algo que os produtos conseguem, de fato, consumir e evoluir.

Anna Puertas

CDPO - INDT Innovation

A arquitetura por trás de um design system

Um design system não é uma biblioteca de componentes. É uma arquitetura para transformar decisões de design em algo que os produtos conseguem, de fato, consumir e evoluir.

No primeiro artigo desta série, escrevi sobre os 10 paradigmas centrais dos design systems, os modelos mentais que considero essenciais para construir e escalar um design system.

No segundo, falei sobre por que design systems falham, os antipadrões que minam a adoção aos poucos, geram frustração nos times e, no fim, empurram as equipes a construir suas próprias soluções por conta própria.

Este artigo é sobre a parte que normalmente se discute bem menos: a arquitetura por trás de um design system.

Onde os tokens deveriam viver? Como os componentes deveriam consumi-los? Como se lida com temas? Onde terminam as responsabilidades do design system e começam as responsabilidades específicas de cada produto? E, provavelmente a pergunta mais importante de todas: como construir um design system capaz de sustentar múltiplos produtos sem transformar o time de design system em um gargalo?

Ao longo dos anos, cheguei à conclusão de que faz sentido pensar em um design system como um conjunto de camadas.

None

Tokens

Fundações (primitivos)

Componentes

Padrões (patterns)

Experiências de produto

Cada camada tem uma responsabilidade clara. E é justamente quando essas responsabilidades se misturam - quando um componente carrega regra de negócio, ou quando um produto começa a sobrescrever tokens na marra - que o sistema começa a rachar.

Vamos por partes.

Camada 1 - Tokens: a fonte única de verdade

Tokens são a unidade mais atômica de decisão de design: cor, espaçamento, tipografia, elevação, raio de borda, duração de animação. Sozinhos, não significam nada. O valor deles está em serem referenciados, não copiados.

Aqui eu costumo separar os tokens em três níveis:

Tokens globais (core) - os valores brutos. blue-500, space-4, font-size-16. Não carregam intenção, só existem para serem a matéria-prima de tudo o que vem depois.

Tokens semânticos - a camada onde o significado entra. color-background-primary, color-text-danger, space-between-elements. Um token semântico aponta para um token global, mas comunica intenção de uso, não apenas valor.

Tokens de componente - a camada mais específica. button-background-hover, input-border-focus. Apontam para tokens semânticos e existem para dar a um componente a flexibilidade de se ajustar sem quebrar a cadeia de decisão.

Onde eles deveriam viver? Em uma única fonte de verdade, versionada, fora do código de qualquer produto específico - normalmente em uma ferramenta como Figma Variables, sincronizada com um pipeline (Style Dictionary é o exemplo mais comum) que gera os artefatos para cada plataforma: CSS custom properties, JSON, XML para Android, Swift para iOS. O ponto central é que ninguém deveria escrever um valor de cor à mão em um componente. Se está fazendo isso, o token está faltando - e a resposta é criar o token, não abrir uma exceção.

Camada 2 - Fundações: as regras antes dos componentes

Antes de existir um componente, existem regras: grid, breakpoints, escala tipográfica, escala de espaçamento, princípios de acessibilidade mínimos (contraste, área de toque, foco visível). Essa camada é frequentemente esquecida porque não é "visível" como um componente, mas é o que garante consistência entre componentes que nunca vão se encontrar no mesmo Figma file.

Camada 3 - Componentes: onde tokens viram interface

Um componente bem construído não decide valores - ele consome tokens semânticos e de componente. Essa é a regra mais importante da camada: componente não hardcoda, componente referencia.

É também aqui que a questão dos temas se resolve com elegância. Um tema não deveria ser um componente diferente, nem um fork de código. Um tema é uma troca de valores na camada

de tokens semânticos - o componente continua sendo exatamente o mesmo, só que agora aponta para outro conjunto de tokens. Dark mode, white-label, marca B para um produto B: tudo isso é resolvido na camada de tokens, nunca na camada de componente. No momento em que um time começa a duplicar componentes para "dar conta" de um tema, é sinal de que a arquitetura de tokens tem um buraco.

Camada 4 - Padrões: onde a composição acontece

Padrões (patterns) são composições de componentes que resolvem um problema recorrente - um formulário de cadastro, um fluxo de confirmação, um estado vazio. Diferente dos componentes, os padrões carregam mais contexto de uso e, por isso, têm menos rigidez. É perfeitamente saudável que um padrão seja compartilhado como referência e vocabulário comum, sem exigir que todo produto o implemente pixel a pixel do mesmo jeito.

É nessa camada que normalmente recomendo mais liberdade aos times de produto - desde que a composição continue sendo feita com os componentes do sistema, e não com componentes "quase iguais" criados do zero.

Camada 5 - Produto: onde o design system para

E aqui chegamos à pergunta que mais gera atrito: onde termina a responsabilidade do design system e começa a responsabilidade do produto?

A resposta que uso: o design system é dono de tokens, fundações e componentes. Padrões são um espaço compartilhado. Regra de negócio, lógica específica de fluxo, copy contextual e decisões que só fazem sentido dentro de um produto específico pertencem ao produto - e não deveriam nunca subir para dentro de um componente do sistema.

Quando um time de produto pede "só mais uma prop" para resolver um caso muito específico do seu fluxo, vale a pergunta: isso é uma variação de design, ou é uma regra de negócio disfarçada de prop? Se for a segunda opção, a resposta certa quase sempre é resolver via composição na camada de produto, não inchar o componente.

A pergunta que fica para o final: como escalar sem virar gargalo

Um time de design system pequeno, centralizando toda decisão para múltiplos produtos, quebra em algum momento - não por falta de competência, mas por design organizacional. A arquitetura em camadas que descrevi acima só funciona de verdade quando vem acompanhada de um modelo de governança federado:

O time central é dono inegociável das camadas de tokens, fundações e componentes principais - mudanças ali passam por revisão mais rígida, porque o raio de impacto é grande.

Times de produto podem contribuir com novos padrões, propor novos componentes e até abrir pull requests para os componentes existentes - desde que sigam os contratos definidos (API do componente, tokens disponíveis, guidelines de acessibilidade).

Documentação e ferramentas de self-service substituem boa parte do que seria, de outra forma, uma fila de pedidos. Se a resposta para "como uso este componente nesse caso" já está documentada, ou testável em um playground, o time central não precisa ser consultado.

O gargalo não nasce da existência de um time central - nasce da ausência de contratos claros entre as camadas. Quando cada camada tem uma fronteira de responsabilidade bem definida, múltiplos produtos conseguem consumir o mesmo sistema em paralelo, sem que cada mudança precise passar pela mesma mesa.


No próximo artigo da série, quero entrar em outro tema que costuma aparecer junto dessa conversa de arquitetura: como medir se um design system está, de fato, cumprindo o que promete - adoção não é a mesma coisa que sucesso.



© INDT - Instituto de Desenvolvimento Tecnológico. Todos os direitos reservados.

Manaus, AM / São Paulo, SP

© INDT - Instituto de Desenvolvimento Tecnológico. Todos os direitos reservados.

Manaus, AM / São Paulo, SP

© INDT - Instituto de Desenvolvimento Tecnológico. Todos os direitos reservados.

Manaus, AM / São Paulo, SP