Desenhando um design system que sobrevive aos seus designers
Um design system morre quando quem o fez vai embora. Os que vivem gravam decisões em tokens e restrições, não na memória.
Já auditei produtos cujo design system era bonito, documentado e morto. O designer que o construiu saiu, o engenheiro que o mantinha mudou de time, e em um ano toda tela nova era feita com estilos avulsos porque ninguém mais sabia as regras. O sistema estava na cabeça deles. Quando saíram, ele saiu junto.
Um design system que sobrevive é aquele em que as decisões vivem no código, em uma forma que o compilador e o linter conseguem impor, e em que um engenheiro novo consegue construir uma tela correta na primeira semana sem perguntar a ninguém.
Tokens são o contrato, não os componentes
A parte duradoura de um design system não é o botão. É o conjunto de valores nomeados de que o botão é feito: espaçamento, papéis de cor, escala tipográfica, raios, sombras, durações de animação. Esses são os tokens, e são a camada que sobrevive a qualquer biblioteca de componentes ou framework.
A disciplina é nomear semanticamente. Um token chamado blue-500 não diz nada sobre quando usar. Um token chamado surface-interactive ou text-danger diz exatamente quando, e permite mudar a cor real para dark mode ou para um rebrand sem tocar em um único componente. Todo valor cru em um arquivo de componente é uma decisão que alguém vai ter que redescobrir.
Exporto tokens como uma fonte única da verdade que gera as variáveis CSS, as constantes TypeScript e a biblioteca da ferramenta de design. Quando eles se descolam, e vão se descolar se mantidos separadamente, o sistema já está morrendo.
Restrinja as props
O segundo mecanismo de sobrevivência é que componentes aceitam decisões, não estilos. Um botão recebe uma variante e um tamanho de uma união fechada. Não recebe um className que deixa qualquer um sobrescrever o padding, e não recebe uma prop style. Parece restritivo no primeiro dia. É o que mantém o produto visualmente coerente no dia setecentos, quando quarenta engenheiros entregaram telas.
TypeScript impõe isso de graça. Uma variante tipada como união de quatro strings não vira uma quinta sem um pull request no sistema, e esse pull request é onde a conversa de design acontece. Válvulas de escape existem, mas são nomeadas, feias e fáceis de grep, para que uma auditoria consiga contá-las.
Acessibilidade vive nos primitivos ou em lugar nenhum. Anéis de foco, navegação por teclado, papéis ARIA e contraste são propriedades dos componentes base, testadas uma vez, herdadas em todo lugar. Um sistema que deixa acessibilidade para cada tela decidiu não tê-la.
Documentação que não apodrece
Documentação escrita se descola. Exemplos que compilam, não. Todo componente vem com exemplos de uso que são código real, renderizados em um catálogo e executados no CI, de modo que uma mudança que quebra um componente falha o build da própria documentação.
O catálogo também é onde design e engenharia se encontram. Quando um designer propõe um padrão novo, a pergunta é se ele pode ser construído com os tokens e componentes existentes. Se sim, é entregue. Se não, o sistema cresce de propósito, com nome e regra, em vez de por acidente em um branch de feature.
Propriedade e o caminho de depreciação
Um sistema sem dono não tem futuro. Alguém, com nome, decide o que entra e o que sai. Isso é um trabalho de meio período em uma empresa pequena e um time em uma grande, mas não pode ser ninguém.
Nada é removido sem um período de depreciação, um aviso de lint apontando para o substituto e um codemod quando a mudança é mecânica. Um sistema que quebra seus consumidores os ensina a fazer fork, e um design system com fork são dois design systems mortos.
O teste que rodo em qualquer design system é simples. Dê a um engenheiro novo uma tela do roadmap do produto e um dia. Se ele consegue construir sem um valor de cor cru, um padding customizado ou uma pergunta a um designer, o sistema está vivo. Se não consegue, já se foi, estejam ou não as pessoas que o construíram ainda lá.