Quem escreve
Vitonsky se apresenta como engenheiro de software e entusiasta de código aberto, e é fundador da PrimeBits, time de engenharia B2B. No currículo que ele mesmo linka na página About, aparecem mais de treze anos de trabalho em projetos complexos e times distribuídos, passagem pela RingCentral entre 2021 e 2023 e, desde outubro de 2023, pela Spearbit Labs. Dois itens desse currículo pesam no assunto do ensaio: entre 2018 e 2021 ele criou um design system unificado usado em mais de sete projetos, e mantém o ElegantUI, kit de UI que descreve como modular, composto só das funcionalidades realmente necessárias. Fora do front-end, é o autor do Linguist Translate, extensão de tradução que roda no próprio dispositivo e que ele contabiliza em mais de 180 mil usuários diários.
O problema: decidir estilo na hora de chamar
O ensaio abre com o mesmo botão “Save changes” escrito duas vezes: primeiro como uma parede de classes utilitárias do Tailwind, depois como um atributo style em HTML puro. Para Vitonsky, os dois casos são a mesma coisa, e ele dá um nome a ela: inlining. O estilo é decidido no ponto da chamada, instância por instância, em vez de ser nomeado uma vez e reaproveitado. O mecanismo, escreve, não importa.
Fora dos custos óbvios de tamanho de página e cache, ele lista três problemas de fundo. Não dá para garantir consistência visual nem dentro de um único arquivo. O código não carrega semântica, então não dá para saber o que aquilo significa. E não existe sistema por trás, o que torna a manutenção difícil, inclusive com LLM: o estilo é propenso a erro e exige muitas iterações até ficar certo.
Variante: o visual inteiro, com nome
A primeira parte da solução é a variante, que ele define como o estilo autocontido que descreve por completo todos os aspectos visuais de um componente, sob um nome semântico. Na prática, a chamada vira `<Button variant=”primary”>` no lugar da lista de propriedades.
A exigência que ele faz da variante é a parte rigorosa: ela precisa conter todos os detalhes de implementação do visual, da geometria interna às cores e à tipografia, e não pode esperar que algo externo complete o trabalho, seja um reset global, uma font-family solta ou qualquer estilo aplicado no lugar. É isso, segundo ele, que torna um design system observável: dá para enxergar quais variantes de um componente existem e atualizar todas de uma vez.
Modificador: variação declarada, não escapatória
A segunda parte responde à tentação de projeto grande. Vitonsky mostra uma chamada em que radius, fontSize, fontWeight e fontFamily entram como props ao lado da variante, e observa que isso é o mesmo problema de novo, só que tipado: as props sobrescrevem a variante de fora, a variante deixa de definir o visual final e as sobrescritas não acompanham mudanças. Troque a variante ou introduza um esquema de cores novo, e elas saem de sincronia em silêncio.
No lugar disso, o modificador. Ele é parte da API do componente, no mesmo nível da variante, e não uma saída lateral em volta dela: `<Button variant=”primary” size=”xl”>`. O limite também está escrito. Quando muitos modificadores se acumulam numa mesma chamada, o sinal é criar outra variante, com nome próprio. A disciplina, resume o autor, é sobre onde uma decisão de estilo pode morar e quando uma combinação recorrente já merece nome.
A mesma regra em três stacks
Para mostrar que a ideia não depende de ferramenta, o ensaio implementa o modificador `size=”xl”` de três jeitos: uma classe em CSS puro no estilo BEM, um seletor `&[data-size=”xl”]` em CSS Modules do Mantine e uma receita de tema do Chakra UI. Os dois últimos batem com a documentação oficial. O Mantine expõe a prop size como atributo `data-size` no elemento raiz de todo componente que a suporta. O Chakra organiza o botão em uma recipe com a chave `variants`.
Vale notar a diferença de vocabulário nesse último caso: dentro da receita do Chakra, `variant` e `size` ficam os dois aninhados sob `variants`. O que o ensaio separa em variante e modificador, a ferramenta chama pelo mesmo nome.
O que dizem as fontes que ele cita
As referências do texto sustentam o argumento quando abertas na origem. A página do MDN sobre o atributo style, linkada no exemplo de HTML puro, recomenda definir estilos em arquivo separado e diz que o atributo serve sobretudo para estilização rápida, por exemplo em teste. O post que ele linka na expressão “reset global” é de Jens Oliver Meiert, publicado em 2017 e atualizado em 2024, e defende que resets e normalizadores são praticamente inúteis. A página do Tailwind que ele aponta se chama “Styling with utility classes” e trata justamente de montar componentes complexos a partir de um conjunto restrito de utilitários.
O tema também não é novo para o autor. O ensaio linka dois textos dele mesmo: “Build Systems, Not Heroes”, de outubro de 2024, e “The most big problem of UI kits”, de maio de 2022, que já resumia o defeito dos kits de UI como falta de design modular.
O fecho
A conclusão é modesta de propósito. A abordagem cabe em quase qualquer kit de UI, inclusive nos que não foram desenhados com essa disciplina em mente. E quem a segue, escreve Vitonsky, acaba com um design system mesmo sem ter partido para construir um, porque será obrigado a identificar as unidades reutilizáveis da própria interface.


