# Open Pencil vs Penpot: Comparación de arquitectura y rendimiento
¿Por qué comparar? OpenPencil existe porque las plataformas de diseño cerradas controlan lo que es posible. Entender las diferencias arquitectónicas muestra lo que una alternativa abierta y local-first puede hacer diferente.
::: info Renderer WASM de Penpot
Penpot 2.x incluye un renderer Rust/Skia WASM (`render-wasm/v1`) activable vía flags del servidor o el parámetro URL `?wasm=true`. El renderer SVG antiguo sigue siendo el predeterminado. Esta página cubre ambos.
Open Pencil es **~11× más pequeño** — y ese es el punto. No es una simplificación; es una arquitectura fundamentalmente diferente.
## 2. Arquitectura
### Open Pencil: cliente monolítico
```
┌─────────────────────────────────┐
│ Tauri (shell nativo) │
│ ┌───────────────────────────┐ │
│ │ Vue 3 + TypeScript │ │
│ │ ┌─────────┐ ┌──────────┐│ │
│ │ │ Editor │ │ Kiwi ││ │
│ │ │ Store │ │ Codec ││ │
│ │ └────┬─────┘ └──────────┘│ │
│ │ │ │ │
│ │ ┌────▼────────────────┐ │ │
│ │ │ Scene Graph (TS) │ │ │
│ │ │ Map<string,Node> │ │ │
│ │ └────┬────────────────┘ │ │
│ │ │ │ │
│ │ ┌────▼────┐ ┌──────────┐│ │
│ │ │ Skia │ │ Yoga ││ │
│ │ │CanvasKit│ │ Layout ││ │
│ │ │ (WASM) │ │ (WASM) ││ │
│ │ └─────────┘ └──────────┘│ │
│ └───────────────────────────┘ │
└─────────────────────────────────┘
```
**Todo en un proceso.** Sin servidor, sin base de datos, sin Docker. El grafo de escena es un `Map<string, SceneNode>` plano en TypeScript. El renderizado llama a Skia CanvasKit directamente desde TS. El layout es Yoga WASM llamado síncronamente.
**Mínimo 5+ servicios.** PostgreSQL para persistencia, Redis (Valkey) para pub/sub y caché, MinIO para almacenamiento de assets, un backend JVM, un exportador Node.js (Chromium headless), más el frontend ClojureScript.
### Veredicto: Arquitectura
La arquitectura de proceso único de Open Pencil elimina: latencia de red entre frontend y backend, overhead de serialización/deserialización en los límites de servicios, complejidad de orquestación de contenedores y overhead de consultas de base de datos.
## 3. Pipeline de renderizado
### Open Pencil: TS → CanvasKit WASM (directo)
```typescript
// renderer.ts — llamadas directas a CanvasKit desde TypeScript
renderSceneToCanvas(canvas, graph, pageId) {
this.fillPaint.setColor(...)
canvas.drawRRect(rrect, this.fillPaint)
}
```
- **1 cruce de límite:** TS → WASM (CanvasKit)
- El grafo de escena vive en el heap JS — sin serialización para renderizar
→ descomponer a primitivas + empaquetar en binario en memoria lineal WASM
→ Rust WASM (vía Emscripten C FFI)
→ skia-safe (bindings Rust de Skia)
→ Skia (WebGL)
```
Cuando está deshabilitado (predeterminado), las formas se renderizan como un árbol DOM SVG. Cuando está habilitado, usa un sistema de renderizado basado en tiles con 11 superficies separadas y caché de hasta 1024 entradas.
| Modelo de renderizado | Inmediato/redibujado completo | Caché por tiles |
| Gestión de superficies | 1 superficie | 11 superficies |
| Overhead de memoria | Bajo (sin caché de tiles) | Alto (1024 entradas caché) |
| Complejidad de código | 1.646 LOC | 22.000 LOC |
| Código inseguro | Ninguno | Estado global `unsafe` |
## 4. Grafo de escena y modelo de datos
### Open Pencil
```typescript
// Mapa plano, búsqueda O(1)
nodes: Map<string,SceneNode>
// 29 tipos de nodo del esquema Kiwi de Figma
// ~390 campos por NodeChange (compatible con Figma)
```
- Interfaces TypeScript con tipos estrictos
- GUIDs coinciden con el formato `sessionID:localID` de Figma
- Acceso directo a propiedades — sin capas de indirección
### Penpot
- Datos distribuidos en `common/` (49.600 LOC de .cljc)
- Módulos de geometría separados para flex layout, grid layout, constraints, bounds, esquinas, efectos
- Validación de esquema en runtime (Malli)
- Los datos deben cruzar el límite CLJS→Rust para renderizado
### Veredicto: Modelo de datos
Open Pencil reutiliza el esquema probado de Figma (194 definiciones Kiwi) directamente en TypeScript — cero traducción. Penpot mantiene su propio sistema de tipos a través de Clojure/ClojureScript/Rust, requiriendo sincronización manual entre los tres.
Penpot mantiene **dos motores de layout independientes** que deben producir resultados idénticos.
### Veredicto: Layout
Open Pencil delega en una librería probada (Yoga, usada por React Native en miles de millones de dispositivos) en 314 líneas. Penpot mantiene ~3.000+ LOC de código de layout personalizado duplicado.
## 6. Formato de archivo y compatibilidad con Figma
### Open Pencil
- **Formato binario Kiwi nativo** — misma serialización que usa Figma internamente
- Import directo de archivos `.fig` vía codec Kiwi extraído (2.178 LOC esquema + 551 LOC codec)
- Soporte de pegado desde el portapapeles de Figma
- Compatible con el protocolo multiplayer de Figma
### Penpot
- **Archivo ZIP** (`.penpot`) con manifiestos JSON y assets binarios
- Sin import nativo de `.fig`
- Tres versiones de formato con sistema de migración
### Veredicto: Formato de archivo
Open Pencil tiene una ventaja significativa — puede leer archivos Figma nativamente y pegar datos del portapapeles de Figma.
110 líneas. Closures forward/inverse que capturan estado mínimo.
### Penpot
Gestión de estado usa Potok (librería tipo Redux para átomos ClojureScript). Undo almacena vectores de cambios inversos (máximo 50 entradas), con transacciones y auto-expiración tras 20 segundos.
### Veredicto: Estado
El enfoque de Open Pencil es más simple y con menos overhead.
## 8. Experiencia de desarrollo
| Métrica | Open Pencil | Penpot |
|---------|-------------|--------|
| Setup de dev | `bun install && bun dev` | Docker Compose + JVM + Node + Rust toolchain |
| Recarga en caliente | Vite HMR (~50ms) | shadow-cljs (segundos) |
OpenPencil incluye un [comando `eval`](/programmable/cli/scripting) que proporciona una API de Plugin compatible con Figma para scripting headless. Además, 90 herramientas AI disponibles vía chat integrado, servidor MCP (stdio + HTTP) y CLI. Penpot tiene sistema de plugins con ejecución sandboxed pero sin API de scripting headless ni integración MCP.
Open Pencil es arquitectónicamente más ligero — un renderer CanvasKit de proceso único en ~26K LOC de TypeScript, compatible con Figma por diseño. Penpot es una plataforma full-stack con ~299K LOC. Ambos ofrecen colaboración en tiempo real (P2P vs servidor). Penpot tiene ecosistema de plugins y exportación PDF en servidor; Open Pencil tiene scripting headless compatible con Figma, **90 herramientas AI/MCP**, exportación SVG y app desktop nativa.