Lienzo y código: creación de las capas de código de Figma



¿Y si pudieras diseñar y crear en el mismo lienzo? Así es como creamos las capas de código que unen el diseño y el código.
Compartir Lienzo y código: creación de las capas de código de Figma
Ilustraciones de Fiona Ye
La semana pasada, lanzamos las capas de código en versión beta, un nuevo tipo de capa en Figma Sites que se genera mediante código React. Los usuarios pueden usar las capas de código para aprovechar todo el potencial de la web en el lienzo visual, creando experiencias interactivas con formularios, sombreadores, interacciones y las API. Al mismo tiempo, las capas de código funcionan como cualquier otra capa de Figma, ya que se pueden anidar dentro de marcos, usar en componentes y mover y redimensionar libremente en el lienzo. Además, puedes convertir al instante los diseños creados en Figma en capas de código con solo hacer clic en un botón y añadir comportamiento usando el mismo modelo de IA que utiliza Figma Make.
Crear capas de código en Figma nos obligó a conciliar dos modelos diferentes de pensar en el software: el diseño y el código. Actualmente, el lienzo visual de Figma es un entorno abierto y flexible que permite a los usuarios iterar rápidamente sobre los diseños. El código ofrece más posibilidades, pero es más estructurado: requiere una organización jerárquica y una sintaxis precisa. Para reconciliar estos dos modelos, necesitábamos crear un enfoque híbrido que honrara la naturaleza rápida y exploratoria del diseño, a la vez que desbloqueara todas las capacidades del código.
Para lograrlo, tuvimos que superar tres retos:
- Integrar las capas de código y los componentes de forma natural en el ecosistema de Figma
- Crear un IDE potente pero fácil de usar que permitiera personalizar el código
- Facilitar la colaboración entre diseñadores y desarrolladores
El código como material
El código suele estar estructurado como un sistema de archivos: un árbol de directorios en el que los archivos de código son los nodos de las hojas. Aunque este modelo es ideal para el desarrollo, cuesta encajarlo con el lienzo espacial 2D de Figma. Por ejemplo, los objetos pueden estar en cualquier parte del lienzo visual, mientras que los archivos de código se encuentran en una ubicación concreta del sistema de archivos. Esta discrepancia plantea retos prácticos para el flujo de trabajo: ¿cómo se copia una capa visual cuando corresponde a una ubicación de archivo específica? ¿Cuál es la fuente de verdad: el lienzo o el sistema de archivos? ¿Debería la clonación de una capa de código crear una instancia de la misma —como es habitual en el código— o crear una versión bifurcada, que es como funciona tradicionalmente la duplicación en Figma?
Sabíamos que necesitábamos que el código en Figma resultara familiar tanto para los diseñadores como para los desarrolladores, y eso significaba que los usuarios debían poder seguir manipulando libremente las capas de código en el lienzo espacial. La solución a la que llegamos fue implementar las capas de código como un nuevo elemento básico del lienzo. Las capas de código se comportan como cualquier otra capa, con total flexibilidad espacial (lo que incluye moverlas, redimensionarlas y reorganizarlas) y una integración perfecta en la disposición (como su colocación en pilas de disposición automática). Pero lo más importante es que se pueden duplicar y modificar fácilmente, imitando la naturaleza libre y experimental del lienzo visual. Esto permite crear y comparar diferentes versiones del código una al lado de la otra. Normalmente, hacer dos copias del código para compararlas requiere crear ramas de Git separadas, pero con las capas de código es tan fácil como pulsar ⌥ y arrastrar. Esto crea automáticamente una bifurcación del código fuente para poder hacer cambios rápidos.
Decidimos apostar por React porque su modelo de componentes se ajusta perfectamente a la idea que tiene Figma de los componentes. Los componentes de Figma son bloques de creación reutilizables y flexibles que los diseñadores usan para construir interfaces. React funciona de la misma manera: los desarrolladores combinan componentes React reutilizables para crear pantallas y aplicaciones. Además, las propiedades de React se corresponden directamente con la noción de propiedades de los componentes de Figma, por lo que las hemos vinculado; puedes definir propiedades en el código y luego editarlas visualmente con controles personalizables como conmutadores, controles deslizantes y menús desplegables.

Un IDE con baterías incluidas en la web
Aunque las capas de código pueden crearse y editarse íntegramente con IA, sabíamos que los usuarios también querrían editar el código directamente para disponer de total flexibilidad Para que esto funcionara a la perfección, incorporamos una experiencia moderna de edición de código en Figma, empezando por nuestra elección del motor principal para el IDE: CodeMirror.
CodeMirror ofrece una base extensible para la edición de código en la web, que nos permite definir extensiones para funciones como temas cromáticos, buscar y reemplazar, y números de línea. En muchos casos, tuvimos que anular los comportamientos predeterminados para integrar el editor de código en Figma; por ejemplo, sustituimos el comportamiento predeterminado de deshacer/rehacer de CodeMirror por una implementación personalizada basada en nuestra propia pila de deshacer.
Desde el principio nos dimos cuenta de que el rendimiento podía suponer un obstáculo, sobre todo con bases de código grandes. Las tareas del IDE, como la agrupación de archivos y la comprobación de tipos, pueden ser lentas y, como JavaScript tiene un único subproceso, pueden hacer que la IU se cuelgue al procesar archivos grandes. Para que el entorno de código de Figma siga siendo rápido, ejecutamos la mayor parte de la cadena de herramientas de desarrollo en un Web Worker. Dentro del Web Worker, utilizamos esbuild (creado por el cofundador de Figma, Evan Wallace) para acelerar los tiempos de empaquetado, y Tailwind v4 con Lightning CSS para una compilación eficiente de estilos. Estas herramientas están escritas parcialmente en código nativo y compiladas a WebAssembly, lo que proporciona un aumento significativo del rendimiento.
Para que la gestión de dependencias sea lo más sencilla posible, instalamos automáticamente los paquetes importados desde NPM o una URL de ESM. No hace falta configurar un archivo package.json: solo tienes que importar las bibliotecas que necesites y empezar a crear en un entorno de pruebas seguro. La mayoría de los paquetes están preconfigurados en Figma, incluidos los favoritos de la comunidad como Motion y React-Three-Fiber.

Capas de código colaborativas
La colaboración multiusuario es el núcleo de Figma, ya que permite a los equipos trabajar juntos de forma eficiente para diseñar y lanzar productos excelentes. Nuestra tecnología multiusuario permite la sincronización simultánea de muchos campos de los nodos, como la posición y el color. Pero nunca se había utilizado para un campo tan complejo como el código fuente, que puede llegar a tener miles de líneas de texto.
Este nuevo requisito nos dio la oportunidad de replantearnos nuestro enfoque. La solución más sencilla para sincronizar las modificaciones es que la última versión escrita prevalezca, es decir, que los cambios de cada usuario sobrescriban los que hayan hecho los demás. Esto funciona bien con fragmentos de texto cortos, como partes del texto de UX en un diseño de Figma, pero falla cuando se editan archivos de código fuente grandes al mismo tiempo, sobre todo con conexiones lentas. También vimos que este problema empeoraba cuando los modelos de IA hacían ediciones simultáneas en el código, creando conflictos adicionales.
La transformación operativa (OT) es una técnica de resolución de conflictos que transforma operaciones simultáneas para lograr la convergencia, ajustándolas en función de su orden de ejecución y su contexto.
Así que buscamos alternativas mejores y recurrimos a algoritmos clásicos de edición colaborativa de texto, como las transformaciones operacionales (OT) y los tipos de datos replicados sin conflictos (CRDT). Las OT transforman las operaciones simultáneas para que se puedan aplicar sin conflictos. Constituyen la tecnología básica de muchos editores de texto colaborativos, como Google Docs. Sin embargo, se ralentizan al fusionar archivos con muchos conflictos, ya que todas las ediciones conflictivas deben transformarse entre sí.
Los tipos de datos replicados sin conflictos (CRDT) son estructuras de datos que garantizan la consistencia eventual, asegurando que todas las réplicas converjan en el mismo estado, independientemente del orden de las operaciones.
Por el contrario, la mayoría de los CRDT tratan cada carácter como una entidad independiente. Esto facilita significativamente la fusión de ediciones, pero conlleva una mayor sobrecarga de memoria. Para procesar las actualizaciones, es necesario reconstruir todo el historial del documento en memoria, incluso si no hay ediciones simultáneas (que es el caso práctico más común). Esto provoca una sobrecarga de memoria y reduce el rendimiento.
Por suerte, un artículo publicado el año pasado presentó Event Graph Walker (Eg-walker), un nuevo algoritmo que combina la mayoría de las ventajas de los OT y los CRDT. Eg-walker representa las modificaciones como un gráfico causal de eventos acíclico y dirigido. Su algoritmo es similar a un rebase de Git; reorganiza varias ramas divergentes en un orden lineal. Para fusionar eventos simultáneos, Eg-walker crea temporalmente una estructura CRDT. Una vez que se completa su algoritmo de resolución, Eg-walker descarta el CRDT interno, liberando memoria. En el caso ideal de ediciones secuenciales y sin conflictos, las actualizaciones tienen un coste casi nulo. Como resultado, es tan rápido como los CRDT a la hora de fusionar, pero tiene una sobrecarga de memoria mínima, como los OT.

Dadas las ventajas que ofrece en cuanto a rendimiento y memoria, usamos el algoritmo Eg-walker para crear el servicio de colaboración multiusuario para las capas de código. Cuando un usuario edita un archivo de código, el cliente envía una lista de cambios al servidor. El servidor reconcilia los cambios simultáneos de todos los clientes activos usando Eg-walker y devuelve una lista actualizada de cambios, resolviendo cualquier conflicto. Con esta arquitectura, el servicio multiusuario se encarga del trabajo de fusión más costoso en términos computacionales para todos los clientes, lo que permite tiempos de carga iniciales rápidos y una experiencia de usuario fluida incluso con sistemas de archivos de gran tamaño.
El futuro del código y el diseño
Inventar por principios
Bret Victor, un influyente escritor, investigador y diseñador de interfaces, describe “una forma de vivir la vida de la que la mayoría de la gente no habla“. Mira su charla completa sobre cómo encontrar tu principio rector —algo que consideres importante, necesario y correcto— y cómo utilizarlo para motivarte.
Las capas de código son solo el principio del código en Figma. Tenemos previsto incorporar una manipulación aún más directa a las capas de código para reducir aún más la brecha entre los flujos de trabajo de programación y diseño, lo que permitirá a los usuarios cambiar sin problemas de un medio a otro según lo que necesiten en cada momento.
En su charla “Inventar por principios“, el diseñador de interfaces Bret Victor afirma que “los creadores necesitan una conexión inmediata con lo que están creando… cuando estás creando algo, si haces un cambio o tomas una decisión, necesitas ver el efecto de eso al instante“. A medida que seguimos ampliando las capacidades del código en Figma, nos guiamos por esta idea: en lugar de aislar el diseño y el código en herramientas separadas, todos deberíamos poder crear juntos en un entorno compartido.
Las capas de código ya están disponibles en versión beta en Figma Sites. ¡Estamos deseando ver tus creaciones!

¡Estamos contratando ingenieros! Infórmate sobre cómo es trabajar en Figma, y consulta nuestras vacantes.



