Ir para o conteúdo principal

Tela de trabalho, conheça o código: Construindo as camadas de código do Figma

Darragh BurkeSoftware Engineer, Figma
Alex KernSoftware Engineer, Figma
Uma árvore verde estilizada com cinco painéis semelhantes a janelas mostrando cenas de uma pessoa criando e explorando com ferramentas e formas.Uma árvore verde estilizada com cinco painéis semelhantes a janelas mostrando cenas de uma pessoa criando e explorando com ferramentas e formas.

E se você pudesse projetar e construir na mesma tela de trabalho? Veja como criamos camadas de código para unir design e código.

Compartilhar Tela de trabalho, conheça o código: Construindo as camadas de código do Figma

Ilustrações por Fiona Ye

Na semana passada, lançamos camadas de código em beta, um novo tipo de camada no Figma Sites renderizado por código React. Os usuários podem usar camadas de código para trazer todo o poder da web para a tela de trabalho, criando experiências interativas com formulários, shaders, interações e APIs. Ao mesmo tempo, as camadas de código agem como outras camadas do Figma, pois podem ser aninhadas dentro de quadros, usadas em componentes e movidas e redimensionadas livremente na tela de trabalho. Além disso, os usuários podem converter instantaneamente designs criados no Figma em camadas de código com o clique de um botão e adicionar comportamento usando o mesmo modelo de IA que alimenta o Figma Make.

Os designs podem ser convertidos em camadas de código com um único clique, dando-lhe acesso ao poder total da web.

Construir camadas de código no Figma exigiu que reconciliássemos dois modelos diferentes de pensar sobre software: design e código. Hoje, a tela de trabalho do Figma é um ambiente flexível e aberto que permite aos usuários iterar rapidamente sobre designs. Código desbloqueia mais capacidades, mas é mais estruturado—requere organização hierárquica e sintaxe precisa. Para reconciliar esses dois modelos, precisamos criar uma abordagem híbrida que honrasse a natureza rápida e exploratória do design ao mesmo tempo que desbloqueasse todas as capacidades do código.

Fazer isso com sucesso exigiu a resolução de três desafios:

  1. Integrar camadas e componentes de código naturalmente no ecossistema do Figma
  2. Construir um IDE poderoso e fácil de usar para impulsionar a personalização de código
  3. Habilitar a colaboração multiplayer entre designers e desenvolvedores

Código como material

O código é tradicionalmente estruturado como um sistema de arquivos—uma árvore de diretórios, com arquivos de código como os nós folha. Embora este modelo seja ótimo para desenvolvimento, é difícil conciliá-lo com o espaço bidimensional da tela de trabalho do Figma. Por exemplo, objetos podem existir em qualquer lugar na tela de trabalho visual, enquanto arquivos de código existem em um local especificado no sistema de arquivos. Essa incompatibilidade cria desafios práticos para o fluxo de trabalho: Como você copia uma camada visual quando ela corresponde a um local específico do arquivo? A fonte da verdade é a tela de trabalho ou um sistema de arquivos? Clonar uma camada de código deve criar uma instância dela — como é comum no código — ou criar uma versão bifurcada, que é como a duplicação no Figma tradicionalmente funciona?

Sabíamos que precisávamos de código no Figma para que fosse familiar tanto para designers quanto para desenvolvedores, o que significava que os usuários deveriam manter a capacidade de manipular livremente as camadas de código na tela de trabalho. A solução a que chegamos foi implementar camadas de código como uma nova tela de trabalho primitiva. As camadas de código se comportam como qualquer outra camada, com completa flexibilidade espacial (incluindo mover, redimensionar e redefinir hierarquia) e integração perfeita ao layout (como posicionamento em pilhas de autolayout). Mais crucialmente, eles podem ser duplicados e iterados facilmente, imitando a natureza livre e experimental de uma tela de trabalho. Isso permite a criação e comparação de diferentes versões de código lado a lado. Normalmente, fazer duas cópias de código para comparação requer a criação de ramificações git separadas, mas com camadas de código, é tão fácil quanto pressionar ⌥ e arrastar. Isso cria automaticamente um fork do código-fonte para experimentação rápida.

Optamos por suportar o React porque seu modelo de componentes se alinha de forma próxima com a noção de componentes do Figma. Os componentes no Figma são blocos de construção reutilizáveis e flexíveis que os designers usam para construir interfaces. O React funciona da mesma maneira—os desenvolvedores combinam componentes reutilizáveis do React para construir telas e apps. Além disso, as props do React correspondem diretamente ao conceito de propriedades de componente do Figma, por isso nós as vinculamos. Assim, você pode definir propriedades no código e depois editá-las visualmente usando controles customizáveis, como alternadores, deslizadores e menus suspensos.

Um componente de UI de cubo 3D com rotação automática e sensibilidade de zoom ativada, mostrado em um painel de visualização escuro com instruções de interação.Um componente de UI de cubo 3D com rotação automática e sensibilidade de zoom ativada, mostrado em um painel de visualização escuro com instruções de interação.
As camadas de código parecem exatamente como as camadas normais no Figma. Propriedades permitem flexibilidade e reutilização.

Um IDE completo e pronto para uso na web

Embora camadas de código possam ser criadas e editadas inteiramente com IA, sabíamos que os usuários também gostariam de editar o código diretamente para ter total flexibilidade. Para tornar isso contínuo, incorporamos uma experiência de edição de código moderno no Figma, começando com nossa escolha para o motor principal para o IDE: CodeMirror.

O CodeMirror fornece uma base extensível para edição de código baseada na web, permitindo-nos definir extensões para recursos como temas de cores, busca e substituição, e números de linha. Em muitos casos, precisávamos sobrepor comportamentos padrão para integrar o editor de código no Figma; por exemplo, substituímos o comportamento padrão de desfazer/refazer do CodeMirror por uma implementação personalizada baseada na nossa própria pilha de desfazer.

Reconhecemos desde cedo que o desempenho poderia se tornar um gargalo, especialmente para grandes bases de código. Tarefas do IDE como empacotamento e verificação de tipos podem ser lentas e, como o JS é single-threaded, elas podem causar travamentos na UI ao processar arquivos grandes. Para manter o ambiente de código do Figma rápido, executamos a maior parte do conjunto de ferramentas de desenvolvimento em um Web Worker. Dentro do worker, usamos o esbuild (criado pelo cofundador da Figma, Evan Wallace) para tempos rápidos de empacotamento, e o Tailwind v4 com Lightning CSS para compilação eficiente de estilo. Essas ferramentas são parcialmente escritas em código nativo e compiladas para WebAssembly, proporcionando um aumento significativo de desempenho.

Para minimizar a complexidade do gerenciamento de dependências, instalamos automaticamente pacotes importados do NPM ou de uma URL ESM. Não há necessidade de inicializar um package.json—apenas importe as bibliotecas que você precisa e comece a construir em um sandbox seguro. A maioria dos pacotes funcionará diretamente no Figma, incluindo os favoritos da comunidade como Motion e React-Three-Fiber.

Uma interface de design Figma mostrando um editor de código Three.js com um cubo azul 3D renderizado em um plano de fundo de grade escura.Uma interface de design Figma mostrando um editor de código Three.js com um cubo azul 3D renderizado em um plano de fundo de grade escura.
O IDE para camadas de código vem com uma cadeia de ferramentas TypeScript completa, incluindo suporte para módulos NPM e ESM.

Tornando as camadas de código colaborativas

A colaboração multiplayer é o coração do Figma, permitindo que as equipes trabalhem juntas de forma eficiente para projetar e entregar ótimas experiências. Nossa tecnologia colaborativa suporta a sincronização simultânea para muitos campos de nó, como posição e cor. Mas isso nunca tinha sido usado para um campo tão complexo quanto o código-fonte, que pode potencialmente ter milhares de linhas de texto.

Este novo requisito apresentou uma oportunidade para repensar nossa abordagem. A solução mais simples para sincronizar edições é a last-write-wins, onde as alterações de cada usuário substituem o que outros usuários modificaram. Isso funciona para pequenos trechos de texto, como partes de UX em um design do Figma, mas quebra quando se edita arquivos de código-fonte grandes simultaneamente, especialmente em conexões mais lentas. Também vimos que esse problema se agravou quando modelos de IA fizeram edições simultâneas no código, criando conflitos adicionais.

Transformação operacional (OT) é uma técnica de resolução de conflitos que transforma operações simultâneas para alcançar a convergência ajustando as operações com base na ordem de execução e no contexto.

Portanto, buscamos alternativas melhores, recorrendo a algoritmos clássicos de edição de texto colaborativa, como Transformações Operacionais (OTs) e Tipos de Dados Replicados Sem Conflito (CRDTs). OTs transformam operações concorrentes para que possam ser aplicadas sem conflitos. Elas formam a tecnologia fundamental para muitos editores de texto colaborativos, como o Google Docs. No entanto, elas diminuem a velocidade ao mesclar arquivos com muitos conflitos, pois todas as edições conflitantes devem ser transformadas umas contra as outras.

Tipos de dados replicados sem conflitos (CRDTs) são estruturas de dados que garantem consistência eventual, assegurando que todas as réplicas convergem para o mesmo estado, independentemente da ordem das operações.

Por outro lado, a maioria dos CRDTs trata cada caractere como uma entidade independente. Isso torna a fusão de edições significativamente mais fácil, mas resulta em um maior consumo de memória. Para processar atualizações, todo o histórico do documento deve ser reconstruído na memória, mesmo que não haja edições simultâneas (o que é o caso de uso mais comum). Isso cria um inchaço de memória e reduz o desempenho.

Felizmente, um artigo publicado no ano passado introduziu o Event Graph Walker (Eg-walker), um novo algoritmo com a maioria dos benefícios da OT e dos CRDTs. Eg-walker representa edições como um grafo de eventos causais direcionado e acíclico. Seu algoritmo é análogo a um rebase do git; ele rearranja várias ramificações divergentes em uma ordem linear. Para mesclar eventos concorrentes, o Eg-walker constrói temporariamente uma estrutura CRDT. Após a conclusão de seu algoritmo de resolução, o Eg-walker descarta o CRDT interno, liberando memória. No caminho feliz de edições sequenciais e não conflitantes, as atualizações são quase de custo zero. Como resultado, é tão rápido quanto CRDTs na fusão, mas tem um uso mínimo de memória, como OTs.

Um diagrama visual que explica o algoritmo de rebase EG-Walker usando sequências de clientes com codificação por cores e inserções de texto.Um diagrama visual que explica o algoritmo de rebase EG-Walker usando sequências de clientes com codificação por cores e inserções de texto.
Eg-walker usa uma abordagem de “recuar e aplicar” para resolver conflitos, similar ao git rebase.

Dadas as vantagens de desempenho e memória, usamos o algoritmo Eg-walker para construir o serviço de colaboração colaborativo para camadas de código. Quando um usuário edita um arquivo de código, o cliente envia uma lista de edições para o servidor. O servidor reconcilia edições simultâneas de todos os clientes ativos usando o Eg-walker e envia de volta uma lista atualizada de edições, resolvendo quaisquer conflitos. Com essa arquitetura, o serviço colaborativo lida com o trabalho de mesclagem mais computacionalmente caro para todos os clientes, permitindo tempos de carregamento iniciais rápidos e uma experiência do usuário eficiente, mesmo para sistemas de arquivos grandes.

O futuro do código e do design

Inventando com Princípios

Bret Victor, um escritor influente, pesquisador e designer de interfaces, descreve "uma maneira de viver sua vida sobre a qual a maioria das pessoas não fala." Assista à palestra completa dele sobre encontrar seu princípio orientador—algo que você acredita ser importante, necessário e correto—e usar isso para te motivar.

As camadas de código são apenas o começo para o código no Figma. Prevemos trazer ainda mais manipulação direta para camadas de código para fechar ainda mais a lacuna entre fluxos de trabalho de código e design, permitindo que os usuários alternem perfeitamente entre meios, dependendo do que precisam em qualquer momento.

Em sua palestra "Inventing On Principle," o designer de interfaces Bret Victor diz que “os criadores precisam de uma conexão imediata com o que estão criando... quando você está fazendo algo, se você faz uma mudança ou toma uma decisão, você precisa ver o efeito disso imediatamente.” À medida que continuamos a expandir as capacidades de código no Figma, somos guiados por esta ideia: em vez de isolar o design e o código em ferramentas separadas, todos devemos ser capazes de criar juntos em um ambiente compartilhado.

As camadas de código estão em beta agora no Figma Sites. Mal podemos esperar para ver o que você vai construir!

Um design gráfico estilizado apresentando uma grande forma semelhante a uma flor cinza, cercada por formas geométricas coloridas e pixels sobre um plano de fundo verde, com "877A7A" exibido verticalmente no lado direito.Um design gráfico estilizado apresentando uma grande forma semelhante a uma flor cinza, cercada por formas geométricas coloridas e pixels sobre um plano de fundo verde, com "877A7A" exibido verticalmente no lado direito.

Estamos contratando engenheiros! Saiba mais sobre a vida na Figma e veja nossas vagas abertas.

Create and collaborate with Figma

Get started for free