Skip to content

4B Pen y Penpot: arquitectura y rendimiento ​

4B Pen y Penpot son herramientas de diseño de código abierto con objetivos y arquitecturas distintos.

Renderizador WASM de Penpot

Penpot 2.x incluye el renderizador Rust/Skia WASM render-wasm/v1, que se activa mediante opciones del servidor o ?wasm=true. El renderizador SVG sigue siendo el predeterminado. La comparación tiene en cuenta ambas opciones.

1. Tamaño del código ​

Métrica4B PenPenpot
Lines of codeunas 26.000unas 299.000
Archivos fuenteunos 143unos 2.900
LenguajesTypeScript, VueClojure, ClojureScript, Rust, JavaScript, SQL, SCSS
Renderizadorunas 3.200 líneas, TypeScript22.000 líneas, Rust/Skia WASM
Interfazunas 4.500 líneasunas 175.000 líneas, CLJS y SCSS
ServidorNinguno, arquitectura local32.600 líneas y 151 archivos SQL
Proporción1×unas 11×

4B Pen es unas once veces más pequeño. La diferencia se debe sobre todo a la arquitectura, no únicamente al número de funciones.

2. Arquitectura ​

4B Pen: un solo proceso cliente ​

text
┌─────────────────────────────────┐
│         Tauri native shell      │
│  ┌───────────────────────────┐  │
│  │  Vue 3 + TypeScript       │  │
│  │  Editor + Kiwi codec      │  │
│  │  SceneGraph in TypeScript │  │
│  │  CanvasKit + Yoga WASM    │  │
│  └───────────────────────────┘  │
└─────────────────────────────────┘

Editor, SceneGraph, códec de archivos y renderizador se ejecutan en el mismo proceso. No se necesita servidor, base de datos ni Docker. SceneGraph se almacena como Map<string, SceneNode>. TypeScript llama directamente a CanvasKit y Yoga WASM calcula la disposición de forma síncrona.

Penpot: plataforma Client-Server ​

text
┌───────────────────────────────────────────────────────┐
│                    Docker Compose                     │
│  ClojureScript frontend │ Clojure/JVM backend        │
│  Rust/Skia WASM         │ PostgreSQL, Valkey, MinIO  │
│  Chromium exporter      │ MCP server                 │
└───────────────────────────────────────────────────────┘

Un despliegue completo de Penpot incluye interfaz, servidor JVM, PostgreSQL, Valkey, MinIO y un exportador basado en Chromium sin interfaz. El entorno de desarrollo requiere Docker Compose, JVM, Node y las herramientas de Rust.

4B Pen evita latencia de red, serialización entre servicios, coordinación de contenedores y consultas de base de datos en las operaciones habituales. Penpot está pensado como plataforma multiusuario alojada en un servidor; 4B Pen prioriza la edición local con baja latencia.

3. Proceso de renderizado ​

4B Pen: TypeScript → CanvasKit WASM ​

typescript
renderSceneToCanvas(canvas, graph, pageId) {
  this.fillPaint.setColor(...)
  canvas.drawRRect(rrect, this.fillPaint)
}
  • Paso directo de TypeScript a WASM.
  • SceneGraph permanece en el JavaScript heap y no se serializa antes del Rendering.
  • El renderizador contiene unas 3.200 líneas distribuidas en módulos especializados.

Penpot: ClojureScript → Rust WASM → Skia ​

Con el renderizador WASM activado:

text
ClojureScript → JavaScript
  → descomposición y Binary packing en WASM linear memory
  → Rust WASM mediante Emscripten C FFI
  → skia-safe
  → Skia/WebGL

Sin WASM, cada Shape se renderiza como SVG DOM element mediante React/Reagent.

En modo WASM, cada UUID se divide en cuatro u32, cada transformación en seis f32, los rellenos y contornos se codifican en binario y las propiedades básicas de una forma ocupan una estructura de 104 bytes. El renderizador usa caché de teselas, áreas de interés, once superficies y estado global mutable mediante unsafe { STATE.as_mut() }.

El Tile system prepara zonas próximas al Viewport y almacena hasta 1.024 Textures. 4B Pen vuelve a renderizar toda la zona visible.

Aspecto4B PenPenpot
JavaScript → WASMCalls directos con objetos TypeScriptStructures codificadas en Binary
ModeloRender completo del Viewport visibleTile cache
Surfaces111
Caché adicionalSin Tile cacheHasta 1.024 Tiles
Tamaño del renderizadorunas 3.200 líneas22.000 líneas
Código no seguroNingunoEstado global mediante unsafe

El Path directo de CanvasKit necesita menos procesamiento intermedio en documentos pequeños y medianos. El Tile system de Penpot puede resultar ventajoso en documentos con más de 100.000 Shapes cuando solo se muestra una zona reducida.

4. SceneGraph y modelo de datos ​

typescript
nodes: Map<string, SceneNode>

4B Pen ofrece:

  • búsqueda por identificador en O(1);
  • 29 tipos de objeto del esquema Kiwi de Figma;
  • unos 390 campos en NodeChange;
  • tipos estrictos de TypeScript;
  • GUID con formato sessionID:localID de Figma.

Penpot mantiene definiciones de tipos propias en Clojure/ClojureScript y Rust. Módulos distintos gestionan colores, componentes, contenedores, rellenos, Grid, modificadores, páginas y rutas. Malli valida esquemas en tiempo de ejecución y los datos de renderizado cruzan el límite CLJS → Rust.

4B Pen utiliza directamente el esquema Kiwi. Penpot debe mantener sincronizado su modelo entre varios lenguajes.

5. Motor de disposición ​

4B Pen usa Yoga WASM de forma síncrona:

typescript
import Yoga from 'yoga-layout'
const root = Yoga.Node.create()
root.setFlexDirection(FlexDirection.Row)
root.calculateLayout()
applyYogaLayout(graph, frame, yogaRoot)

Penpot mantiene implementaciones propias de Flex y Grid en ClojureScript y Rust WASM. Ambos motores deben producir el mismo resultado.

4B Pen utiliza Yoga, incluida una variante con Grid. Penpot mantiene varios miles de líneas de código propio de disposición en dos lenguajes.

6. Formatos y Figma ​

4B Pen ​

  • Formato Binary Kiwi nativo de Figma.
  • Import directo de .fig.
  • Paste de Kiwi binary data desde Figma Clipboard.
  • Wire compatibility con Figma Multiplayer protocol.

Penpot ​

  • .penpot es un ZIP con JSON manifests, Document data, Binary assets y Thumbnails.
  • SVG renderer y Export predeterminados; WASM renderer opcional.
  • Sin Import nativo de .fig.
  • Varias Generations del formato con Migration system.

4B Pen lee .fig y Figma Clipboard directamente. Penpot necesita una vía de Import o Export separada.

7. Estado y deshacer ​

4B Pen usa comandos inversos. Las funciones de avance y retroceso guardan solo el estado necesario; los lotes agrupan varias operaciones.

Penpot usa Potok. UpdateEvent modifica el estado y WatchEvent ejecuta efectos secundarios mediante RxJS. Deshacer almacena vectores de cambios inversos, limita el historial a 50 entradas y agrupa cambios rápidos en transacciones.

Los cambios serializables encajan con la colaboración basada en servidor, pero aumentan la complejidad. El enfoque de 4B Pen es más directo para un editor de un solo proceso.

8. Desarrollo ​

Métrica4B PenPenpot
Setupbun install && bun devDocker Compose, JVM, Node y Rust
HMRViteshadow-cljs
TypesStrict TypeScriptMalli runtime schemas
DesktopTauri v2Browser
Tecnologías principalesTypeScript y VueClojure, ClojureScript, Rust y Docker

9. Rendimiento ​

Escenario4B PenPenpot
Arranque en fríomenos de 2 s con WASMmás de 10 s para servidor, cliente y WASM
Operación habitualDentro de un procesoPosible recorrido de red
FotogramaLlamada directa a SkiaCLJS → JS → WASM FFI → Skia
Memoria baseunos 50 MB en la pestaña del navegadorJVM, base de datos, caché y navegador
Sin conexiónFuncionamiento local completoRequiere servidor
10.000 formasUna pasadaRenderizador por teselas con once superficies

10. Ventajas de Penpot ​

  1. Colaboración mediante servidor: cuentas, control de acceso y almacenamiento central a través de WebSockets.
  2. Exportación PDF: exportador independiente basado en Chromium.
  3. Sistema de plugins: ejecución aislada y API de plugins.
  4. Variables de diseño: compatibilidad integrada.
  5. CSS Grid: implementación propia; 4B Pen usa una variante de Yoga con Grid.
  6. Alojamiento propio: despliegue de una plataforma de equipo mediante Docker.
  7. Madurez: varios años de uso en producción.

11. Scripts y extensibilidad ​

El comando eval proporciona una API compatible con plugins de Figma para scripts sin interfaz, operaciones por lotes y pruebas automatizadas. Además, el chat con AI, el servidor MCP y la CLI ofrecen 90 herramientas para leer, crear, modificar, estructurar, gestionar variables, editar rutas vectoriales, analizar, comparar, ejecutar operaciones booleanas y ordenar.

Penpot ofrece plugins aislados, pero no una API equivalente para scripting sin interfaz ni integración MCP.

Resumen ​

ÁreaVentajaMotivo
Simplicidad4B PenUn proceso en lugar de varios servicios
Renderizado4B PenRuta directa a CanvasKit
Código4B PenUnas 26.000 frente a 299.000 líneas
Compatibilidad con Figma4B PenKiwi y .fig nativos
Desarrollo4B PenTypeScript y Vue frente a Clojure, Rust y Docker
Aplicación de escritorio4B PenTauri nativo
Disposición4B PenYoga frente a dos implementaciones propias
ColaboraciónVentajas distintasPenpot: servidor y control de acceso; 4B Pen: P2P sin alojamiento
Alojamiento propioPenpotDespliegue con Docker
Madurez del ecosistemaPenpotAños de uso en producción

4B Pen es un editor compacto de un solo proceso con renderizador CanvasKit y compatibilidad nativa con .fig. Penpot es una plataforma cliente-servidor completa con Clojure, ClojureScript, Rust, bases de datos y servicios Docker. Ambos ofrecen colaboración con modelos diferentes. Penpot tiene un ecosistema de plugins y exportación PDF; 4B Pen ofrece scripting sin interfaz compatible con Figma, 90 herramientas AI/MCP, exportación SVG y una aplicación de escritorio.

Released under the MIT License.