Caso de estudo de Gabriel Espinheira, engenheiro full-stack sénior
Fabricator UI, shadcn/ui com personalidade própria
Uma biblioteca de componentes React open source que se instala com o CLI do shadcn/ui em projetos que já o usam, com uma linguagem de design própria. Construí-a a dirigir agentes de programação: primeiro commit a 05/10/2026, o CLI no npm como 0.2.1 a 11/10/2026.
Ainda no início: versão 0.3.0, servida a partir do site da documentação.

O que o repositório diz
5.120
itens do registo comparados com ui.shadcn.com em cada push
27
builds de cada componente: 3 primitivas, 9 estilos
62
componentes na documentação
61
ficheiros de estilo que fazem o visual Fabricator
32
sons de interface, sintetizados no browser
5
cenários de instalação construídos de raiz no CI
Contado a partir do repositório a 10/10/2026, no commit a025e94, e da sua execução de CI de 09/10/2026.
Visual próprio, nada para migrar
O shadcn/ui dá às equipas React os seus componentes como código-fonte, através de um CLI e de registos que qualquer pessoa pode publicar. Para dar a uma biblioteca um visual próprio, podia fazer fork desses componentes ou publicar um pacote que ninguém consegue editar, e os dois afastam-se do original.
Queria uma terceira opção: um visual e um movimento próprios, instalados com os comandos que um projeto shadcn/ui já usa, com cada nova versão do original ainda fácil de juntar. Eis de quem é cada parte do trabalho, tudo sob a licença MIT:
- shadcn/ui
- o código dos componentes para três bibliotecas de primitivas, oito estilos, o motor do CLI e a app de documentação de onde partiu
- Fluid Functionalism
- a linguagem de design de Micka Touillaud: superfícies, movimento, hover fluido e barras de scroll
- Meu
- a camada de registo, o estilo Fabricator e as suas substituições, os tokens, os sons e a Pesquisa, o wrapper do CLI, os testes de paridade e de instalação, e o site
Os mesmos componentes, outra sensação
O site da documentação mostra o estilo Fabricator, por isso mostra o que uma instalação lhe dá. Cada filme abaixo é uma gravação do site ao vivo a 11/10/2026.

Um destaque que desliza
Em menus, separadores, barras laterais e tabelas, um destaque salta com uma mola para o item mais próximo do cursor, por isso uma lista nunca pisca de linha em linha e um clique num espaço vazio cai no item destacado. O foco do teclado move o mesmo destaque. Mede os itens pelas suas posições no layout, por isso um popup que ainda está a crescer não o engana, e corre em molas CSS sem biblioteca de animação. Doze componentes usam-no em Base UI e Radix, dez em React Aria.

Oito superfícies, uma cor
Cada superfície é um fundo e uma sombra, sem margens: o anel de 1px da sombra desenha o contorno. Uma cor base, guardada em duas variáveis CSS, dá tom aos oito níveis em modo claro e escuro. O modo claro baixa a luminosidade de cada nível à medida que o tom cresce, porque a cor precisa de espaço abaixo do branco, e os testes verificam que cada nível fica em sRGB e que cada par de texto fica AA em toda a roda de cores.

Uma API sobre três bibliotecas de primitivas
Cada componente tem uma árvore de código para Base UI, Radix e React Aria, com os mesmos nomes, props, variantes e atributos data-slot em cada uma. Mudar a documentação entre elas troca a primitiva por baixo e deixa o componente com o mesmo aspeto. Uma alteração numa árvore chega às três na mesma alteração, e um componente que substitui um do shadcn/ui só acrescenta à sua API.

Movimento em três molas
Cada transição escolhe um de três níveis: 90 ms para hover e popups, 210 ms para seleções e painéis, e 290 ms com um ligeiro ressalto para diálogos. As saídas são cerca de um quarto mais rápidas. Os componentes nunca escrevem milissegundos, por isso uma só variável de escala acelera, abranda ou para todas as animações, e o movimento reduzido mantém os desvanecimentos e tira as deslocações.

Sons sem ficheiros de áudio
Trinta e dois sons de interface são sintetizados no browser com a Web Audio API, cada um alguns tons curtos ou um sopro de ruído filtrado. Cada família de componentes tem o seu material: os botões soam a madeira e os separadores tocam como sinos afinados num acorde. Um componente toca-os a partir de atributos que os componentes já têm, e ficam desligados até alguém os ligar. O catálogo segue a lista publicada por Bencho de funções e tons; a síntese é original.
Placeholders à entrada, estilos à saída
O código de um componente mantém a estrutura e o comportamento no próprio sítio e nomeia tudo o que um estilo pode mudar com uma classe placeholder, como cn-button-variant-outline. Um mapa de estilos transforma cada placeholder em classes Tailwind durante a build. É o próprio modelo do shadcn/ui, e o visual Fabricator é mais um mapa de estilos: 61 ficheiros CSS, um por componente.
Uma só build compila todas as bibliotecas de primitivas em todos os estilos e serve o resultado em dois endereços. O modo Blend compila os componentes extra no estilo que o projeto já usa; o modo Fabricator serve o visual Fabricator completo. O comportamento que o CSS não consegue exprimir, como o Fluid Hover, vive em 48 substituições que só compilam no estilo Fabricator, para que os estilos originais mantenham exatamente o mesmo resultado.
A maioria dos redesigns é uma alteração de CSS.
- Base UI
- Radix
- React Aria
Código dos componentes com placeholders
Mapas de estilos · 8 originais, 1 Fabricator
Build do registo · 27 combinações
Modo Blend · o seu estilo
Modo Fabricator · o seu visual
O CLI do shadcn no seu projeto
Regras que o mantêm encaixável
Um projeto em shadcn/ui deve aceitar um componente Fabricator sem mudar o seu próprio código. As instruções do repositório chamam a estas regras o contrato: uma alteração que quebre uma delas é um erro, mesmo que tudo compile.
Só acrescentar
Um componente que substitui um do shadcn/ui mantém todos os nomes, props, variantes, exports e data-slots. Props e variantes novas são acréscimos opcionais.
Um id de estilo válido, sempre
O components.json mantém um id de estilo original, como base-nova. Um id próprio faria falhar contra ui.shadcn.com todos os shadcn add simples do projeto, por isso o visual Fabricator viaja no endereço do registo.
Dependências com namespace
Os itens Fabricator dependem uns dos outros como @fabricator/nome. Um nome simples refere-se sempre ao item do próprio shadcn/ui, e só se escreve quando essa é a intenção.
O contrato dos tokens
Todas as variáveis CSS do shadcn/ui mantêm o nome e o significado, para que o tema de um projeto passe para lá. Os tokens Fabricator chegam com nomes novos, dentro dos itens que os usam.
Três árvores, uma alteração
Uma alteração ao código de uma biblioteca de primitivas chega às outras duas na mesma alteração, e uma exceção deliberada di-lo no commit.
Reconstruído, nunca editado à mão
Os índices, o mapa de estilos montado e o registo compilado são reconstruídos a partir do código. O código original só entra através de um script de sincronização, num ramo próprio.

As verificações que cada alteração tem de passar
O CI corre em cada pull request e em cada push para o main: uma build completa do registo, lint, tipos e formatação, os testes unitários, a paridade com o original e depois uma build de produção do site e os testes de instalação. Tudo passou no main a 09/10/2026.
Paridade com o original
Cada push compara 5.120 ficheiros compilados do registo com ui.shadcn.com. Tirando o conteúdo de demonstração com nova marca e os itens próprios do Fabricator, coincidem byte a byte, e três correções de erros ficam registadas como exceções deliberadas.
Instalações construídas de raiz
O CLI prepara apps Vite nas três bibliotecas de primitivas, uma app Next.js e um projeto shadcn/ui existente, instala componentes em cada um a partir do registo servido localmente e corre uma build de produção de todos.
Contraste como teste unitário
As cores de estado, a escada de superfícies e o tom são testados para WCAG AA em claro e escuro, o tom em toda a roda de cores na intensidade máxima, para que uma nova cor não saia com texto abaixo de 4,5:1.
Uma build que encravou sem um erro
Na máquina de build normal de 8 GB da Vercel, a build do site era terminada por falta de memória sem mensagem, e as publicações ficavam em Building até serem canceladas. Reproduzi o problema num contentor com os mesmos limites, baixei a build para 7 GB e escrevi o orçamento nas regras do repositório para todos os agentes.
A maioria das linhas é do shadcn
O Fabricator UI parte do repositório do shadcn/ui num commit fixo, e a maioria das suas linhas continua a ser do shadcn, sem alterações. É de propósito: quanto menos ficheiros originais edito, mais barato é juntar a próxima versão do original, por isso o meu trabalho vai para ficheiros novos sempre que possível.
Todos os commits têm o meu nome, e o trabalho aconteceu em sessões de agentes: 23 dos 27 commits creditam o Claude como coautor, e os meus registos locais têm 14 sessões do Claude Code e 15 do Codex no repositório. O PLAN.md regista 13 decisões de arquitetura, e as regras dizem a todos os agentes para o lerem antes de mexer no registo ou no CLI.
Ainda é cedo. O CLI chegou ao npm como 0.2.1 a 11/10/2026, e o registo é servido a partir do site da documentação na Vercel até fabricator-ui.com estar no ar. Os filmes desta página foram compostos e renderizados no Relay, a partir de gravações do site ao vivo.
| Origem | Linhas | Percentagem |
|---|---|---|
| Do shadcn/ui, sem alterações | 301 940 | 57% |
| Do shadcn/ui, editado | 164 218 | 31% |
| Gerado pela build | 20 671 | 4% |
| Acrescentado para o Fabricator UI | 43 562 | 8% |
Os ficheiros editados mudaram com 19.607 linhas acrescentadas e 12.264 removidas, sobretudo conteúdo de demonstração com nova marca. 48 dos ficheiros acrescentados são substituições: cópias de componentes do shadcn/ui com comportamento Fabricator acrescentado.
Uma decisão difícil: tornar-se um registo
Problema
Uma biblioteca com visual e componentes próprios tinha de funcionar nos projetos que as pessoas já têm e acompanhar um original que avança depressa. Entre março e setembro de 2026, o shadcn/ui lançou uma nova versão principal do CLI, uma nova biblioteca de primitivas por defeito e um novo pacote para juntar classes.
Opções
Fazer fork dos componentes e do CLI dá controlo total, mas cada nova versão do original passa a ser uma migração manual, e os projetos existentes não conseguem acrescentar um componente com os comandos que já usam. Um pacote npm em runtime mantém o código num só sítio e tira o código-fonte que as pessoas esperam ter.
Escolha
Tornar-se um registo que o CLI oficial já entende. Um CLI fino com marca própria corre o pacote shadcn fixado e acrescenta as suas predefinições. O código mantém o modelo de placeholders do shadcn, por isso o design é mais um mapa de estilos, o original chega num ramo próprio através de um script de sincronização, e cada push prova que os itens originais continuam iguais a ui.shadcn.com.
Custo
O Fabricator UI fica preso ao contrato do shadcn: nenhuma prop nem token com nome mudado e nenhum id de estilo próprio, por isso o seu visual tem de viajar no endereço do registo. Cada item é construído 27 vezes, e os fragmentos de componentes para cada estilo original fizeram parte do que levou a build do site para lá dos 8 GB da Vercel.
Uma decisão mais pequena: construir o site no meu portátil
A build da Vercel levava sete a nove minutos e a maior parte da memória; o portátil constrói e envia em menos de quatro. O script de publicação envia o resultado final, cerca de 48.000 ficheiros, num só arquivo, porque a Vercel aceita 15.000 por envio. O custo é que as publicações dependem de uma máquina, por isso as publicações em produção recusam-se a correr a partir de algo que não seja um main limpo igual ao GitHub.
Precisa de alguém responsável pela construção?
Estou disponível para uma função a tempo inteiro ou para um projeto por contrato. Leio todas as mensagens pessoalmente e respondo em 2 dias úteis.
- Função a tempo inteiro
Um engenheiro sénior na sua equipa
Remoto no horário europeu, ou híbrido e presencial em Lisboa.Falar sobre uma função - Projeto por contrato
O seu produto, de ponta a ponta
Web, desktop e mobile em TypeScript, Next.js, Convex e Expo, incluindo funcionalidades de IA.Falar sobre um projeto
