Skip to content

OpenPencil и Penpot: архитектура и производительность ​

OpenPencil и Penpot — открытые инструменты дизайна с разными задачами и архитектурой.

WASM-рендерер Penpot

Penpot 2.x включает Rust/Skia WASM-рендерер render-wasm/v1, который включается параметрами сервера или ?wasm=true. По умолчанию по-прежнему используется SVG-рендерер. Ниже рассматриваются оба варианта.

1. Размер кодовой базы ​

ПоказательOpenPencilPenpot
Строк кодаоколо 26 000около 299 000
Исходных файловоколо 143около 2 900
ЯзыкиTypeScript, VueClojure, ClojureScript, Rust, JavaScript, SQL, SCSS
Код отрисовкиоколо 3 200 строк, TypeScript22 000 строк, Rust/Skia WASM
Интерфейсоколо 4 500 стрококоло 175 000 строк, CLJS и SCSS
Серверная частьНет, локальная архитектура32 600 строк и 151 файл SQL
Соотношение1×около 11×

OpenPencil примерно в 11 раз меньше. Это следствие другой архитектуры, а не только меньшего набора возможностей.

2. Архитектура ​

OpenPencil: один клиентский процесс ​

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

Редактор, SceneGraph, кодек файлов и отрисовка работают в одном процессе. Отдельные сервер, база данных и Docker не нужны. SceneGraph хранится как Map<string, SceneNode>. TypeScript напрямую вызывает CanvasKit, а Yoga WASM синхронно рассчитывает компоновку.

Penpot: клиент-серверная платформа ​

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

Для полной установки Penpot нужны интерфейс, серверная часть JVM, PostgreSQL, Valkey, MinIO и экспортёр на основе Chromium без интерфейса. Среда разработки требует Docker Compose, JVM, Node и инструменты Rust.

OpenPencil избегает сетевой задержки, сериализации между службами, управления контейнерами и запросов к базе данных для обычных операций. Penpot рассчитан на многопользовательскую платформу с серверным размещением, а OpenPencil — на локальную работу с минимальной задержкой.

3. Конвейер отрисовки ​

OpenPencil: TypeScript → CanvasKit WASM ​

typescript
renderSceneToCanvas(canvas, graph, pageId) {
  this.fillPaint.setColor(...)
  canvas.drawRRect(rrect, this.fillPaint)
}
  • Один прямой переход из TypeScript в WASM.
  • SceneGraph остаётся в памяти JavaScript и не сериализуется перед отрисовкой.
  • Код отрисовки занимает около 3 200 строк и разделён на специализированные модули.

Penpot: ClojureScript → Rust WASM → Skia ​

text
ClojureScript → JavaScript
  → разложение и бинарная упаковка в память WASM
  → Rust WASM через Emscripten C FFI
  → skia-safe
  → Skia/WebGL

Без WASM каждая фигура отображается как элемент SVG DOM через React/Reagent. В режиме WASM UUID разбивается на четыре u32, преобразование — на шесть f32, заливки и обводки кодируются в двоичном виде, а основные свойства фигуры занимают структуру размером 104 байта.

Система использует кеш плиток, области интереса, 11 поверхностей отрисовки и глобальное изменяемое состояние через unsafe { STATE.as_mut() }. Кеш может хранить до 1024 текстур. OpenPencil перерисовывает видимую область целиком.

АспектOpenPencilPenpot
JavaScript → WASMПрямые вызовы с объектами TypeScriptДвоичные структуры
МодельПолная отрисовка видимой областиКеш плиток
Поверхности111
Дополнительный кешНетДо 1024 плиток
Размер кода отрисовкиоколо 3 200 строк22 000 строк
Небезопасный кодНетГлобальное состояние через unsafe

Прямой путь CanvasKit требует меньше промежуточной обработки для небольших и средних документов. Кеш Penpot может быть выгоднее для документов со 100 000 и более фигур, когда видна лишь малая часть холста.

4. SceneGraph и модель данных ​

typescript
nodes: Map<string, SceneNode>

OpenPencil обеспечивает поиск по идентификатору за O(1), 29 типов объектов из схемы Kiwi, около 390 полей в NodeChange, строгие типы TypeScript и GUID в формате Figma sessionID:localID.

Penpot поддерживает собственные определения типов в Clojure/ClojureScript и Rust. Отдельные модули отвечают за цвета, компоненты, контейнеры, заливки, сетку, модификаторы, страницы и контуры. Malli проверяет схемы во время выполнения, а данные отрисовки пересекают границу CLJS → Rust.

5. Движок компоновки ​

OpenPencil синхронно использует Yoga WASM:

typescript
const root = Yoga.Node.create()
root.setFlexDirection(FlexDirection.Row)
root.calculateLayout()

Penpot поддерживает собственные реализации Flex и Grid в ClojureScript и Rust WASM. Оба движка должны выдавать одинаковый результат. OpenPencil использует Yoga, включая ответвление с поддержкой Grid; Penpot поддерживает несколько тысяч строк собственного кода компоновки на двух языках.

6. Форматы и Figma ​

OpenPencil использует бинарный формат Kiwi Figma, напрямую импортирует .fig, читает данные Kiwi из буфера обмена и совместим с многопользовательским протоколом Figma.

Файл .penpot — ZIP-архив с манифестами JSON, данными документа, бинарными ресурсами и миниатюрами. Penpot не импортирует .fig напрямую и поддерживает несколько поколений формата через систему миграций.

7. Состояние и отмена ​

OpenPencil использует обратные команды: функции применения и отмены сохраняют только необходимое состояние, а несколько операций можно объединить.

Penpot использует Potok. UpdateEvent меняет состояние, WatchEvent выполняет побочные эффекты через RxJS, а история хранит обратные наборы изменений, ограничивается 50 записями и объединяет быстрые изменения в транзакции.

8. Разработка ​

ПоказательOpenPencilPenpot
Подготовкаbun install && bun devDocker Compose, JVM, Node и Rust
Быстрое обновлениеViteshadow-cljs
ТипыСтрогий TypeScriptСхемы Malli во время выполнения
Настольная версияTauri v2Браузер
Основные технологииTypeScript и VueClojure, ClojureScript, Rust и Docker

9. Производительность ​

СценарийOpenPencilPenpot
Холодный запускменее 2 секунд с WASMболее 10 секунд для сервера, клиента и WASM
Обычная операцияВнутри одного процессаВозможен сетевой обмен
КадрПрямой вызов SkiaCLJS → JS → WASM FFI → Skia
Базовая памятьоколо 50 МБ во вкладке браузераJVM, база данных, кеш и браузер
Работа без сетиПолнаяТребует сервера
10 000 фигурОдин проходПлиточная отрисовка с 11 поверхностями

10. Преимущества Penpot ​

  1. Серверная совместная работа: учётные записи, контроль доступа и центральное хранение через WebSockets.
  2. Экспорт PDF: отдельный экспортёр Chromium.
  3. Система плагинов: изолированное выполнение и API плагинов.
  4. Токены дизайна: встроенная поддержка.
  5. CSS Grid: собственная реализация; OpenPencil использует ответвление Yoga с Grid.
  6. Самостоятельное размещение: развёртывание для команды через Docker.
  7. Зрелость: несколько лет эксплуатации.

11. Сценарии и расширяемость ​

Команда eval предоставляет совместимый с Figma Plugin API для сценариев без интерфейса, пакетных операций и автоматизированных тестов. Чат с ИИ, сервер MCP и CLI также предлагают 90 инструментов для чтения, создания, изменения, работы со структурой, переменными, векторными контурами, анализа, сравнения, логических операций и расположения.

Penpot предлагает изолированные плагины, но не имеет сопоставимого API для сценариев без интерфейса или интеграции MCP.

Итоги ​

ОбластьПреимуществоПричина
ПростотаOpenPencilОдин процесс вместо нескольких служб
ОтрисовкаOpenPencilПрямой путь CanvasKit
Кодовая базаOpenPencilОколо 26 000 против 299 000 строк
Совместимость с FigmaOpenPencilНативные Kiwi и .fig
РазработкаOpenPencilTypeScript и Vue вместо Clojure, Rust и Docker
Настольное приложениеOpenPencilTauri
КомпоновкаOpenPencilYoga вместо двух собственных реализаций
Совместная работаРазные преимуществаPenpot: сервер и контроль доступа; OpenPencil: P2P без размещения
Самостоятельное размещениеPenpotРазвёртывание Docker
ЗрелостьPenpotМноголетняя эксплуатация

OpenPencil — компактный редактор в одном процессе с CanvasKit и нативной поддержкой .fig. Penpot — полная клиент-серверная платформа на Clojure, ClojureScript, Rust, базах данных и службах Docker. Оба поддерживают совместную работу, но используют разные модели.

Released under the MIT License.