* docs: polish localized documentation - Rewrite Russian documentation for natural terminology and current source parity\n- Continue the Polish editorial pass across guides and SDK references\n- Refresh shared localized SDK API data imports * docs(pl): complete editorial pass - Rewrite the remaining advanced Vue SDK references\n- Refresh the Figma compatibility matrix against the canonical source\n- Align terminology and behavior across every Polish documentation page * docs(de): complete editorial pass - Rewrite German guides, automation docs, and Vue SDK references\n- Restore current AI, export, component, and variable behavior\n- Refresh the Penpot comparison and Figma compatibility matrix * docs(es): complete editorial pass - Rewrite Spanish guides, automation docs, and Vue SDK references\n- Restore current AI, export, component, and variable behavior\n- Refresh the Penpot comparison and Figma compatibility matrix * docs(fr): complete editorial pass - Rewrite French guides, automation docs, and Vue SDK references\n- Restore current AI, export, component, and variable behavior\n- Refresh the Penpot comparison and Figma compatibility matrix * docs: correct localized terminology - Replace unnecessary English prose with natural localized terminology\n- Derive documentation aliases from named directory roots\n- Preserve English only for identifiers, APIs, and exact product terms * docs(it): continue editorial pass - Rewrite Italian user guides and automation documentation\n- Update Vue SDK composables and component references\n- Restore current AI, export, component, and variable behavior * docs(it): complete editorial pass - Finish Italian advanced SDK and reference documentation\n- Refresh the Penpot comparison and Figma compatibility matrix\n- Replace literal machine translations with natural technical prose * docs(pl): refine property panel terminology * docs: refine remaining localized prose - Replace overfitted English prose in Polish feature documentation\n- Rewrite the Russian property-list reference in natural terminology * docs(ru): rewrite Penpot comparison naturally - Replace remaining English prose with natural Russian\n- Preserve code identifiers and library names only where required * docs: rewrite localized feature overviews naturally - Replace avoidable English prose in German, Spanish, and French\n- Keep identifiers and product names unchanged * docs(de): refine property panel terminology * docs: refine Spanish and French SDK terminology * docs(ru): continue full prose audit - Rewrite homepage, setup, navigation, and guide index naturally\n- Restore missing zoom shortcuts * docs(ru): audit user and automation guides - Rewrite selection, collaboration, and automation prose naturally\n- Preserve API identifiers while localizing ordinary terminology * docs(ru): audit CLI inspection and analysis * docs(ru): audit Vue SDK overview and guides * docs(ru): audit Vue SDK API prose - Localize ordinary component and composable terminology\n- Preserve API symbols and code identifiers * docs(ru): audit advanced and gradient API references * docs(ru): finish advanced API prose audit * docs(ru): audit JSX renderer guide * docs(ru): audit CLI export and scripting guides * docs(pl): audit Penpot comparison prose * docs(pl): audit selection and automation guides * docs(pl): audit homepage and variable guides * docs(pl): audit vector, layers, and Pen guides * docs(pl): audit Auto layout and shape guides * docs(pl): audit context menu and export guides * docs(pl): audit JSX and analysis guides * docs(pl): audit AI Chat guide * docs(pl): audit components and CLI inspection * docs(pl): audit scripting and SDK overview prose * docs(pl): audit SDK API indexes * docs(pl): audit SDK component references * docs(pl): audit SDK composable references * docs(ru): refine usePosition terminology * docs(pl): audit advanced SDK references * docs(pl): audit Figma compatibility matrix * docs(pl): finish residual SDK terminology audit * docs(pl): finish component terminology audit * docs(pl): finish SDK guide terminology audit * docs(de): begin full user guide prose audit * docs(de): audit navigation, Pen, and layers guides * docs(de): audit Auto Layout, shapes, menu, and export * docs(de): audit components, text, and vector guides * docs(de): audit variables and automation overview * docs(de): audit AI Chat and collaboration guides * docs(de): audit CLI inspection, analysis, and export * docs(de): audit scripting and JSX guides * docs(de): audit Vue SDK overview and guides * docs(de): audit SDK API indexes * docs(de): audit SDK component references * docs(de): audit SDK composable references * docs(de): audit advanced SDK references * docs(de): audit Penpot comparison prose * docs(de): audit Figma compatibility reference * docs(es): begin full user guide prose audit * docs(es): audit document organization guides * docs(es): audit editing workflow guides * docs(es): audit automation and collaboration prose * docs(es): audit CLI inspection and export guides * docs(es): audit CLI scripting guide * docs(es): audit JSX and feature overview prose * docs(es): audit Penpot comparison prose * docs(es): audit SDK overview and guides * docs(es): begin SDK component reference audit * docs(es): audit SDK navigation component references * docs(es): audit SDK color and layout components * docs(es): begin SDK composable reference audit * docs(es): audit SDK property composable references * docs(es): audit SDK editor composable references * docs(es): begin advanced SDK reference audit * docs(es): audit advanced SDK state references * docs(es): complete advanced SDK reference audit * docs(es): audit Figma compatibility reference * docs(es): complete residual terminology sweep * docs(fr): begin full prose second audit * docs(fr): audit AI and variables prose * docs(fr): audit core user guide prose * docs(fr): audit editing workflow guides * docs(fr): audit CLI and JSX prose * docs(fr): audit Penpot comparison prose * docs(fr): audit SDK overview and guides * docs(fr): begin SDK API reference audit * docs(fr): audit SDK navigation component references * docs(fr): audit SDK color and layout components * docs(fr): begin SDK composable reference audit * docs(fr): audit SDK property composable references * docs(fr): audit editor composables and advanced APIs * docs(fr): audit advanced SDK state references * docs(fr): complete advanced SDK reference audit * docs(fr): audit Figma compatibility reference * docs(fr): complete residual terminology sweep * docs(it): begin full prose second audit * docs(it): audit document workflow guides * docs(it): audit editing and automation prose * docs(it): audit CLI and JSX prose * docs(it): audit Penpot comparison and SDK guides * docs(it): begin SDK API reference audit * docs(it): audit SDK component and state references * docs(it): audit residual SDK references * docs(it): audit Figma compatibility reference * docs(it): complete residual terminology sweep * docs(i18n): verify residual locale terminology
11 KiB
OpenPencil y Penpot: arquitectura y rendimiento
OpenPencil y Penpot son herramientas de diseño de código abierto con objetivos y arquitecturas distintos.
::: info 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étrica | OpenPencil | Penpot |
|---|---|---|
| Lines of code | unas 26.000 | unas 299.000 |
| Archivos fuente | unos 143 | unos 2.900 |
| Lenguajes | TypeScript, Vue | Clojure, ClojureScript, Rust, JavaScript, SQL, SCSS |
| Renderizador | unas 3.200 líneas, TypeScript | 22.000 líneas, Rust/Skia WASM |
| Interfaz | unas 4.500 líneas | unas 175.000 líneas, CLJS y SCSS |
| Servidor | Ninguno, arquitectura local | 32.600 líneas y 151 archivos SQL |
| Proporción | 1× | unas 11× |
OpenPencil 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
OpenPencil: un solo proceso cliente
┌─────────────────────────────────┐
│ 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
┌───────────────────────────────────────────────────────┐
│ 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.
OpenPencil 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; OpenPencil prioriza la edición local con baja latencia.
3. Proceso de renderizado
OpenPencil: TypeScript → CanvasKit WASM
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:
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. OpenPencil vuelve a renderizar toda la zona visible.
| Aspecto | OpenPencil | Penpot |
|---|---|---|
| JavaScript → WASM | Calls directos con objetos TypeScript | Structures codificadas en Binary |
| Modelo | Render completo del Viewport visible | Tile cache |
| Surfaces | 1 | 11 |
| Caché adicional | Sin Tile cache | Hasta 1.024 Tiles |
| Tamaño del renderizador | unas 3.200 líneas | 22.000 líneas |
| Código no seguro | Ninguno | Estado 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
nodes: Map<string, SceneNode>
OpenPencil 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:localIDde 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.
OpenPencil utiliza directamente el esquema Kiwi. Penpot debe mantener sincronizado su modelo entre varios lenguajes.
5. Motor de disposición
OpenPencil usa Yoga WASM de forma síncrona:
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.
OpenPencil 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
OpenPencil
- 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
.penpotes 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.
OpenPencil lee .fig y Figma Clipboard directamente. Penpot necesita una vía de Import o Export separada.
7. Estado y deshacer
OpenPencil 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 OpenPencil es más directo para un editor de un solo proceso.
8. Desarrollo
| Métrica | OpenPencil | Penpot |
|---|---|---|
| Setup | bun install && bun dev |
Docker Compose, JVM, Node y Rust |
| HMR | Vite | shadow-cljs |
| Types | Strict TypeScript | Malli runtime schemas |
| Desktop | Tauri v2 | Browser |
| Tecnologías principales | TypeScript y Vue | Clojure, ClojureScript, Rust y Docker |
9. Rendimiento
| Escenario | OpenPencil | Penpot |
|---|---|---|
| Arranque en frío | menos de 2 s con WASM | más de 10 s para servidor, cliente y WASM |
| Operación habitual | Dentro de un proceso | Posible recorrido de red |
| Fotograma | Llamada directa a Skia | CLJS → JS → WASM FFI → Skia |
| Memoria base | unos 50 MB en la pestaña del navegador | JVM, base de datos, caché y navegador |
| Sin conexión | Funcionamiento local completo | Requiere servidor |
| 10.000 formas | Una pasada | Renderizador por teselas con once superficies |
10. Ventajas de Penpot
- Colaboración mediante servidor: cuentas, control de acceso y almacenamiento central a través de WebSockets.
- Exportación PDF: exportador independiente basado en Chromium.
- Sistema de plugins: ejecución aislada y API de plugins.
- Variables de diseño: compatibilidad integrada.
- CSS Grid: implementación propia; OpenPencil usa una variante de Yoga con Grid.
- Alojamiento propio: despliegue de una plataforma de equipo mediante Docker.
- 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
| Área | Ventaja | Motivo |
|---|---|---|
| Simplicidad | OpenPencil | Un proceso en lugar de varios servicios |
| Renderizado | OpenPencil | Ruta directa a CanvasKit |
| Código | OpenPencil | Unas 26.000 frente a 299.000 líneas |
| Compatibilidad con Figma | OpenPencil | Kiwi y .fig nativos |
| Desarrollo | OpenPencil | TypeScript y Vue frente a Clojure, Rust y Docker |
| Aplicación de escritorio | OpenPencil | Tauri nativo |
| Disposición | OpenPencil | Yoga frente a dos implementaciones propias |
| Colaboración | Ventajas distintas | Penpot: servidor y control de acceso; OpenPencil: P2P sin alojamiento |
| Alojamiento propio | Penpot | Despliegue con Docker |
| Madurez del ecosistema | Penpot | Años de uso en producción |
OpenPencil 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; OpenPencil ofrece scripting sin interfaz compatible con Figma, 90 herramientas AI/MCP, exportación SVG y una aplicación de escritorio.