Penpot 2026 深度实战:当开源设计工具学会与AI协作——从 Clojure 后端到 SVG 渲染引擎、从 Design Tokens 到 MCP 集成的生产级完全指南(2026)
前言:为什么程序员需要关注一个设计工具?
作为一名程序员,你可能觉得设计工具是设计师的事。但现实是:2026 年的软件开发,设计与代码的边界正在急剧模糊。AI 编程工具能生成前端页面,但生成的 UI 常常千篇一律;设计师用 Figma 做出精美稿子,但交付给开发者的标注常常对不上;团队设计资产锁在第三方平台,数据主权成问题。
Penpot 就是在这个背景下崛起的。它在 GitHub 上已经积累了超过 51,000 颗星,单日增长超过 700 颗,是设计工具领域增长最快的开源项目。它不仅仅是一个「开源 Figma 替代品」——它重新思考了设计与代码协作的范式,原生支持 SVG 渲染、Design Tokens、AI 工作流和 MCP(Model Context Protocol)集成。
本文将从程序员的视角,深入剖析 Penpot 的技术架构、核心实现、部署实践和与 AI 的融合方案,帮助你理解为什么这个用 Clojure 写的后端、用 SVG 渲染画布的设计工具,正在改变设计与开发的协作方式。
一、Penpot 是什么?——重新定义设计与代码协作
1.1 起源与定位
Penpot 由 Kaleidos 开源社区开发,2022 年首次发布。它的核心理念是:设计工具应该像代码一样开放、可协作、可自托管。
与 Figma 的核心差异在于:
- 完全开源(MPL-2.0 许可证),代码透明,可审计
- 基于 SVG 标准渲染,而不是 Canvas 位图——意味着每个设计元素都是矢量对象,开发者可以直接拿到 SVG 代码
- 原生自托管,设计资产完全存储在自己的服务器上
- Design Tokens 原生支持,设计系统的颜色、字体、间距可以作为结构化数据导出
- AI 工作流集成,支持 MCP 协议,AI Agent 可以直接读取和操作设计文件
1.2 技术栈全景
Penpot 的技术选型在 2026 年的开源项目中相当独特:
| 组件 | 技术栈 | 说明 |
|---|---|---|
| 前端 | ClojureScript + React | 函数式响应式前端 |
| 后端 | Clojure + JVM | 核心业务逻辑 |
| 数据库 | PostgreSQL 15 | 用户数据、设计元数据 |
| 缓存/消息 | Redis 7 | 实时协作、WebSocket 消息队列 |
| 导出服务 | Node.js | PNG/SVG/PDF 导出 |
| 渲染引擎 | SVG(W3C 标准) | 画布渲染 |
| 容器化 | Docker Compose | 一键部署 |
| 反向代理 | Caddy / Nginx | HTTPS + 自动证书 |
Clojure 在 Web 开发中并不常见,这个选择背后的技术考量值得深入分析。
二、架构深度分析——Clojure 后端为什么能扛住实时协作?
2.1 为什么是 Clojure?
Clojure 是 JVM 上的函数式编程语言,在并发处理方面有天然优势。对于一个需要支持多用户实时协作的设计工具,这个选择有几个关键技术理由:
软件事务内存(STM):Clojure 的 STM 提供了一种无需锁的并发控制机制。当多个用户同时编辑同一个设计文件时,STM 保证了数据一致性,而不会像传统锁机制那样产生死锁或性能瓶颈。
;; Penpot 中的 STM 使用示例(简化示意)
(defn update-shape-attributes!
[file-id shape-id new-attrs]
(dosync
(let [file (get-file file-id)
shape (get-shape file shape-id)]
(alter file update-shape shape-id
(fn [s] (merge s new-attrs))))))
不可变数据结构:Clojure 的持久化数据结构(persistent data structures)在修改时返回新版本,旧版本不受影响。这意味着多用户并发编辑时,每个用户看到的是一致的设计状态快照,而不会出现「部分更新」的中间态。
REPL 驱动开发:Clojure 的 REPL(Read-Eval-Print Loop)让开发者可以在运行时动态注入代码、调试状态。对于分布式系统来说,这意味着可以在不重启服务的情况下诊断问题。
2.2 实时协作架构
Penpot 的实时协作基于 WebSocket + Redis 的发布/订阅模式:
用户A ──WebSocket──→ Backend ──→ Redis Pub/Sub ──→ Backend ──WebSocket──→ 用户B
↕
PostgreSQL
核心流程:
- 用户 A 在画布上移动一个矩形
- 前端通过 WebSocket 发送操作消息到后端
- 后端验证操作、更新状态、写入 PostgreSQL
- 后端通过 Redis Pub/Sub 广播变更到所有连接的 Backend 实例
- 其他 Backend 实例收到广播后,通过 WebSocket 推送给订阅该文件的用户 B
冲突解决策略:Penpot 采用了 Operational Transformation(OT) 的简化版本。由于 SVG 元素的属性更新通常是幂等的(比如移动到坐标 x=100, y=200),大多数冲突可以通过「后写入胜出」策略解决。对于更复杂的冲突(如同时删除同一元素),后端会基于操作时间戳进行仲裁。
;; 操作消息结构(简化)
(def operation-msg
{:type :move
:shape-id "rect-001"
:changes {:x 100 :y 200}
:timestamp 1719043200000
:user-id "user-abc"
:file-id "file-xyz"})
2.3 SVG 渲染引擎
这是 Penpot 与 Figma 最本质的技术区别。Figma 使用自定义的 Canvas 渲染引擎(基于 WebGL),而 Penpot 直接使用浏览器原生的 SVG 渲染能力。
SVG 渲染的优势:
- 零渲染代码维护:浏览器厂商已经在 SVG 渲染上投入了大量工程,Penpot 不需要自己写渲染器
- 天然矢量:设计文件的每个元素都是 SVG 节点,导出 SVG 时零损失
- CSS 驱动:样式通过 CSS 属性控制,开发者可以直接复制样式代码
- 无障碍支持:SVG 原生支持 ARIA 标签,比 Canvas 更利于无障碍访问
- DOM 操作:可以用标准的 DOM API 操作设计元素,方便集成自动化工具
SVG 渲染的挑战:
- 性能瓶颈:当画布上有超过 10,000 个元素时,DOM 操作的开销会显著增加
- 复杂效果限制:CSS 滤镜的性能不如 WebGL 自定义着色器
- 内存占用:大量 SVG 节点的 DOM 内存占用高于 Canvas 像素缓冲区
Penpot 的应对策略是分层渲染:将设计文件分为多个图层(Layers),每个图层是一个独立的 <svg> 元素。当用户编辑某一层时,只有该层的 SVG 会重新计算布局,其他层保持不变。
<!-- Penpot 画布的 SVG 结构(简化) -->
<div class="penpot-canvas">
<svg class="layer" data-id="layer-background" width="1920" height="1080">
<rect x="0" y="0" width="1920" height="1080" fill="#ffffff"/>
</svg>
<svg class="layer" data-id="layer-components" width="1920" height="1080">
<g class="component" data-id="btn-primary">
<rect x="10" y="10" width="120" height="40" rx="8" fill="#1A73E8"/>
<text x="70" y="35" text-anchor="middle" fill="#ffffff" font-size="14">Submit</text>
</g>
</svg>
<svg class="layer" data-id="layer-guides" width="1920" height="1080">
<!-- 辅助线和对齐指示器 -->
</svg>
</div>
三、核心功能深度实战
3.1 组件系统与变体
Penpot 的组件系统类似于 Figma 的 Components,但有几个独特之处:
组件变体(Component Variants):允许你为同一个组件定义多种状态(如按钮的 Normal / Hover / Disabled 状态),这些变体共享基础结构,只有特定属性不同。
实战步骤:
- 创建一个基础按钮组件
- 选中组件,右键 → 「Create component」
- 右键组件 → 「Add variant」
- 为每个变体设置不同属性
;; 组件变体的数据结构(简化)
(def component-variant
{:id "btn-primary"
:name "Primary Button"
:base {:width 120 :height 40 :border-radius 8}
:variants
[{:id "normal" :fill "#1A73E8" :text-color "#ffffff"}
{:id "hover" :fill "#1557B0" :text-color "#ffffff"}
{:id "disabled":fill "#BDBDBD" :text-color "#757575"
:opacity 0.6}]})
嵌套组件:组件内部可以引用其他组件,形成嵌套结构。比如一个卡片组件内嵌按钮组件、头像组件和文字组件。当修改子组件时,所有引用它的父组件都会自动更新。
3.2 Design Tokens——设计与代码的统一语言
这是 Penpot 2026 年最值得关注的特性。Design Tokens 是设计决策的结构化表示——颜色、字体、间距、圆角等设计参数,以一种机器可读的格式存储。
为什么 Design Tokens 重要?
在传统工作流中,设计师在 Figma 中定义颜色为 #1A73E8,开发者在代码中硬编码 #1A73E8。一旦品牌色调整,需要设计师改 Figma、开发者改代码,两步操作,容易漏改。
Design Tokens 解决了这个问题:
设计师定义 Token → Penpot 存储为结构化数据 → 自动同步到代码
Penpot 中的 Design Tokens 实战:
在 Penpot 中创建一个 Design Token 文件:
- 创建新项目 → 选择「Design Tokens」类型
- 定义颜色 Token:
{
"color": {
"primary": {
"$value": "#1A73E8",
"$type": "color",
"$description": "主色调,用于主要按钮和链接"
},
"primary-hover": {
"$value": "#1557B0",
"$type": "color"
},
"background": {
"$value": "#FFFFFF",
"$type": "color"
},
"surface": {
"$value": "#F5F5F5",
"$type": "color"
}
}
}
- 定义间距 Token:
{
"spacing": {
"xs": {"$value": "4px", "$type": "dimension"},
"sm": {"$value": "8px", "$type": "dimension"},
"md": {"$value": "16px", "$type": "dimension"},
"lg": {"$value": "24px", "$type": "dimension"},
"xl": {"$value": "32px", "$type": "dimension"}
}
}
Design Tokens 的数学函数:Penpot 支持在 Token 定义中使用数学表达式,这是 2026 版本的重要特性。
{
"spacing": {
"base": {"$value": "8px", "$type": "dimension"},
"xs": {"$value": "${spacing.base} / 2", "$type": "dimension"},
"sm": {"$value": "${spacing.base}", "$type": "dimension"},
"md": {"$value": "${spacing.base} * 2", "$type": "dimension"},
"lg": {"$value": "${spacing.base} * 3", "$type": "dimension"},
"xl": {"$value": "${spacing.base} * 4", "$type": "dimension"}
}
}
修改 base 的值,所有派生的间距会自动重新计算。这让设计系统的维护变得极其灵活。
导出 Design Tokens:
Penpot 支持导出为标准 JSON 格式,可以直接与 Style Dictionary、Figma Tokens 等工具集成:
# 通过 Penpot API 导出 Design Tokens
curl -sS -X GET \
'https://penpot.yourdomain.com/api/v1/projects/{project-id}/design-tokens/export' \
-H 'Authorization: Bearer <access-token>' \
-o design-tokens.json
3.3 开发者标注面板(Inspect)
Penpot 内置的 Inspect 面板是连接设计师和开发者的桥梁。任何查看者(不需要设计权限)都可以查看设计文件中任意元素的精确规格:
- 尺寸:宽、高、位置(x, y)
- 颜色:HEX、RGB、HSL 格式
- 字体:字体族、字号、行高、字重
- CSS 代码:自动生成 CSS 样式代码
/* Penpot 自动生成的 CSS */
.btn-primary {
width: 120px;
height: 40px;
border-radius: 8px;
background-color: #1A73E8;
display: flex;
align-items: center;
justify-content: center;
}
.btn-primary__text {
font-family: 'Inter', sans-serif;
font-size: 14px;
font-weight: 600;
line-height: 1.2;
color: #FFFFFF;
text-align: center;
}
与 Figma 的关键区别:由于 Penpot 基于 SVG 渲染,生成的 CSS 更贴近实际 DOM 结构。Figma 生成的 CSS 是从 Canvas 绘制信息逆向推导的,常常需要手动调整。Penpot 的 CSS 可以直接复制使用,减少了「翻译」环节。
3.4 原型链接与交互
Penpot 的原型功能支持创建页面间的导航流程:
- 切换到「Prototype」标签
- 选中一个交互元素(如按钮)
- 在右侧面板点击「+」创建交互
- 设置触发条件:Click、Hover、Drag 等
- 连接目标 Frame(页面)
- 设置过渡动画:Instant、Dissolve、Smart Animate
Smart Animate 是 Penpot 的亮点特性。当两个 Frame 之间的元素有相同的组件 ID 时,Smart Animate 会自动计算起始帧和结束帧之间每个元素的位置、大小、透明度差异,生成流畅的过渡动画。你不需要手动编写动画关键帧。
四、Docker 部署实战——从零到生产环境
4.1 基础部署
# 创建部署目录
mkdir -p /opt/penpot && cd /opt/penpot
# 下载官方配置
curl -o docker-compose.yaml \
https://raw.githubusercontent.com/penpot/penpot/main/docker/images/docker-compose.yaml
curl -o config.env \
https://raw.githubusercontent.com/penpot/penpot/main/docker/images/config.env
核心配置项详解:
# config.env 关键配置
PENPOT_FLAGS=enable-registration enable-login-with-password enable-premium-features
PENPOT_SECRET_KEY=$(openssl rand -hex 64) # JWT 签名密钥,必须设置
PENPOT_PUBLIC_URI=https://penpot.yourdomain.com
PENPOT_DATABASE_URI=postgresql://penpot-postgres/penpot
PENPOT_REDIS_URI=redis://penpot-redis/0
PENPOT_ASSETS_STORAGE_BACKEND=assets-fs
PENPOT_STORAGE_ASSETS_FS_DIRECTORY=/opt/data/assets
PENPOT_TELEMETRY_ENABLED=false # 关闭遥测
PENPOT_SMTP_ENABLED=true # 启用邮件(团队邀请必需)
PENPOT_SMTP_HOST=smtp.yourdomain.com
PENPOT_SMTP_PORT=587
PENPOT_SMTP_USERNAME=noreply@yourdomain.com
PENPOT_SMTP_PASSWORD=your_smtp_password
PENPOT_SMTP_TLS=true
PENPOT_SMTP_FROM=noreply@yourdomain.com
4.2 Caddy 自动 HTTPS
Caddy 是推荐的反向代理方案,自动处理 Let's Encrypt 证书:
# 在 docker-compose.yaml 中追加 Caddy 服务
services:
caddy:
image: caddy:2-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
networks:
- penpot
depends_on:
- penpot-frontend
# Caddyfile
penpot.yourdomain.com {
reverse_proxy penpot-frontend:80
}
4.3 启动与验证
# 启动所有服务
docker compose up -d
# 查看服务状态(后端启动约需 60-90 秒)
docker compose ps
# 监控后端日志,等待 "Server started" 输出
docker compose logs -f penpot-backend
# 健康检查
curl -sS https://penpot.yourdomain.com/api/v1/health | jq .
4.4 生产环境优化
PostgreSQL 调优:
-- postgresql.conf 关键参数
shared_buffers = 2GB -- 系统内存的 25%
effective_cache_size = 6GB -- 系统内存的 75%
work_mem = 64MB -- 排序和哈希操作的内存
maintenance_work_mem = 512MB -- 维护操作的内存
random_page_cost = 1.1 -- SSD 优化
max_connections = 200 -- 根据并发用户数调整
Redis 持久化:
# config.env
PENPOT_REDIS_URI=redis://penpot-redis/0
# 在 docker-compose.yaml 中为 Redis 添加持久化
penpot-redis:
image: redis:7
restart: always
command: redis-server --appendonly yes --maxmemory 512mb --maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
networks:
- penpot
备份策略:
#!/bin/bash
# backup-penpot.sh
BACKUP_DIR="/opt/backups/penpot"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
# 备份 PostgreSQL
docker exec penpot-postgres pg_dump -U penpot penpot \
| gzip > $BACKUP_DIR/db_${DATE}.sql.gz
# 备份设计资产
docker cp penpot-frontend:/opt/data/assets $BACKUP_DIR/assets_${DATE}
# 清理 30 天前的备份
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete
find $BACKUP_DIR -maxdepth 1 -type d -mtime +30 -exec rm -rf {} \;
echo "Backup completed: $DATE"
五、API 与 Webhook——将 Penpot 集成到你的工作流
5.1 RESTful API
Penpot 提供了完整的 REST API,支持程序化操作设计文件:
# 获取项目列表
curl -sS -X GET \
'https://penpot.yourdomain.com/api/v1/teams/{team-id}/projects' \
-H 'Authorization: Bearer <access-token>' \
| jq .
# 获取设计文件的页面列表
curl -sS -X GET \
'https://penpot.yourdomain.com/api/v1/files/{file-id}' \
-H 'Authorization: Bearer <access-token>'
# 获取页面中所有组件
curl -sS -X GET \
'https://penpot.yourdomain.com/api/v1/files/{file-id}/pages/{page-id}/components' \
-H 'Authorization: Bearer <access-token>'
5.2 Webhook 事件
Penpot 支持通过 Webhook 订阅设计变更事件:
{
"webhook": {
"url": "https://your-ci-server.com/webhooks/penpot",
"events": ["file:updated", "comment:created", "file:published"],
"secret": "your-webhook-secret"
}
}
典型应用场景:
设计稿更新 → 自动触发组件库生成:当设计师更新组件库时,Webhook 触发 CI/CD 流水线,自动从 Penpot 导出 Design Tokens,生成前端组件代码
评论通知 → Slack 集成:开发者在 Penpot 中对设计稿添加评论,Webhook 将评论推送到 Slack 频道
5.3 GitHub Actions 集成
# .github/workflows/sync-design-tokens.yml
name: Sync Design Tokens from Penpot
on:
schedule:
- cron: '0 2 * * *' # 每天凌晨 2 点同步
workflow_dispatch: # 手动触发
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Export Design Tokens from Penpot
run: |
curl -sS -X GET \
'${{ secrets.PENPOT_API }}/api/v1/projects/${{ secrets.PENPOT_PROJECT }}/design-tokens/export' \
-H "Authorization: Bearer ${{ secrets.PENPOT_TOKEN }}" \
-o tokens/tokens.json
- name: Transform tokens to CSS
run: |
npx style-dictionary \
--config tokens/config.json
- name: Commit updated tokens
run: |
git config user.name "Design Token Bot"
git config user.email "bot@yourdomain.com"
git add src/styles/tokens/
git diff --staged --quiet || git commit -m "chore: sync design tokens from Penpot"
git push
六、AI 工作流与 MCP 集成——2026 年的杀手级特性
6.1 Penpot AI 白皮书核心观点
Penpot 团队在 2026 年发布的 AI 白皮书中提出了一个核心论点:AI 在设计中的作用不是替代设计师,而是成为设计师的「执行者」。
具体来说,AI 可以:
- 根据文本描述生成布局
- 根据设计系统约束自动调整组件
- 将设计稿转换为前端代码
- 分析设计一致性并提出改进建议
但 AI 不应该:
- 独立做出设计决策(颜色、字体、布局风格)
- 在没有设计系统约束的情况下自由创作
- 替代设计师的审美判断
6.2 MCP(Model Context Protocol)集成
MCP 是 AI Agent 与外部工具通信的标准协议。Penpot 通过 MCP 让 AI Agent(如 Claude、Cursor、OpenRouter)能够:
- 读取设计文件:AI 可以理解设计稿的完整结构
- 生成设计建议:AI 基于设计系统约束提出布局方案
- 自动导出代码:AI 将设计稿转换为 React/Vue 组件代码
在 Cursor 中配置 Penpot MCP(5 步完成,无需写代码):
// Cursor 的 MCP 配置文件
{
"mcpServers": {
"penpot": {
"command": "npx",
"args": ["-y", "@penpot/mcp-server"],
"env": {
"PENPOT_URL": "https://penpot.yourdomain.com",
"PENPOT_TOKEN": "your-access-token"
}
}
}
}
在 OpenRouter 中配置 Penpot MCP(6 步完成):
// OpenRouter 配置
{
"tools": [
{
"type": "mcp",
"server": {
"url": "https://your-mcp-gateway.com/penpot",
"headers": {
"Authorization": "Bearer your-openrouter-key"
}
}
}
]
}
6.3 AI 驱动的设计工作流实战
场景:AI 辅助生成符合设计系统的页面布局
- 在 Penpot 中定义好 Design Tokens(颜色、间距、字体)
- 创建基础组件库(按钮、输入框、卡片等)
- 通过 MCP 让 AI 读取设计系统
你(在 Cursor 中):根据 Penpot 中的设计系统,生成一个用户登录页面。
包含:邮箱输入框、密码输入框、登录按钮、忘记密码链接。
遵循设计系统中的间距和颜色规范。
AI 通过 MCP 读取 Penpot 中的 Design Tokens 和组件定义,生成符合规范的前端代码:
// AI 基于Penpot设计系统生成的React组件
import { tokens } from '@/styles/tokens';
export function LoginPage() {
return (
<div style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
minHeight: '100vh',
backgroundColor: tokens.color.background,
padding: tokens.spacing.lg,
}}>
<form style={{
width: '100%',
maxWidth: '400px',
display: 'flex',
flexDirection: 'column',
gap: tokens.spacing.md,
}}>
<input
type="email"
placeholder="邮箱地址"
style={{
height: '40px',
border: `1px solid ${tokens.color.border}`,
borderRadius: tokens.borderRadius.md,
padding: `${tokens.spacing.sm} ${tokens.spacing.md}`,
fontSize: '14px',
}}
/>
<input
type="password"
placeholder="密码"
style={{
height: '40px',
border: `1px solid ${tokens.color.border}`,
borderRadius: tokens.borderRadius.md,
padding: `${tokens.spacing.sm} ${tokens.spacing.md}`,
fontSize: '14px',
}}
/>
<button style={{
height: '40px',
backgroundColor: tokens.color.primary,
color: tokens.color.textOnPrimary,
borderRadius: tokens.borderRadius.md,
fontWeight: 600,
fontSize: '14px',
border: 'none',
cursor: 'pointer',
}}>
登录
</button>
<a href="/forgot-password" style={{
color: tokens.color.primary,
fontSize: '14px',
textAlign: 'center',
}}>
忘记密码?
</a>
</form>
</div>
);
}
关键价值:AI 生成的代码与 Penpot 中的设计系统完全一致,因为 AI 是通过 MCP 直接读取了 Design Tokens 的数值,而不是「猜测」样式。
6.4 Token-Aware Prompting(令牌感知提示)
Penpot 团队提出了一种高效的 AI 提示方法——Token-Aware Prompting。核心理念是:像编写代码接口一样编写 AI 提示词,而不是像写日记一样。
# 好的 AI 提示词(Token-Aware)
## 上下文
设计系统:Penpot 项目 "Brand-Design-System"
Token 文件:/tokens/brand-tokens.json
目标:生成一个产品列表页面
## 约束
- 使用 design-tokens 中的颜色值(不要硬编码)
- 间距使用 spacing token 的倍数
- 按钮使用组件 "btn-primary" 的规格
- 卡片圆角使用 borderRadius.lg
## 输出
- React + TypeScript
- Tailwind CSS(映射到 design tokens)
- 响应式:mobile-first
## 不要
- 不要引入设计系统中不存在的颜色
- 不要使用非标准字体
# 差的 AI 提示词
帮我做一个产品列表页面,好看一点,颜色用蓝色系。
差距是显而易见的。Token-Aware Prompting 把 AI 当作需要精确规格的「代码生成器」,而不是需要模糊描述的「创意助手」。
七、性能优化与扩展
7.1 大文件性能优化
当设计文件超过一定规模时(数百个组件、数千个元素),Penpot 可能出现响应延迟。优化策略:
1. 图层分组:将相关元素编组,减少同一层级的元素数量
画布
├── Background(背景层,通常不编辑)
├── Layout(布局层,包含框架和网格)
├── Components(组件层,可复用组件)
└── Annotations(标注层,开发者和评审查看)
2. 离屏渲染优化:Penpot 对不在视口内的元素使用虚拟化渲染,类似虚拟滚动列表的实现:
;; 视口裁剪逻辑(简化示意)
(defn visible-shapes [viewport-zoom viewport-rect all-shapes]
(filter (fn [shape]
(and
;; 缩放级别合适(太小的元素跳过)
(> (shape-area shape)
(* 4 (/ 1 viewport-zoom)))
;; 在视口范围内(含 10% 缓冲区)
(rects-overlap?
(expand-rect viewport-rect 0.1)
(shape-bounding-box shape))))
all-shapes))
3. 导出性能:对于大型设计文件的导出,Penpot 的 Node.js 导出服务支持:
# 通过 API 触发异步导出
curl -sS -X POST \
'https://penpot.yourdomain.com/api/v1/export' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"fileId": "file-xyz",
"pageId": "page-001",
"format": "png",
"scale": 2,
"async": true
}'
# 返回 {"jobId": "export-abc"}
# 轮询状态
curl -sS 'https://penpot.yourdomain.com/api/v1/export/status/export-abc'
7.2 水平扩展
当单实例无法满足团队规模时,Penpot 支持水平扩展:
┌──→ Penpot Backend 1
Caddy (LB) ──→ ... ├──→ Penpot Backend 2
└──→ Penpot Backend N
↕ ↕
PostgreSQL Redis Cluster
关键点:
- 所有 Backend 实例共享同一个 PostgreSQL
- Redis 使用 Cluster 模式保证消息广播的可靠性
- Caddy 作为负载均衡器,支持轮询和最少连接策略
- 文件级别的亲和性路由(sticky session)可选,但非必需
7.3 对象存储集成
对于大规模部署,建议使用 S3 兼容的对象存储替代本地文件系统:
# config.env - 对象存储配置
PENPOT_ASSETS_STORAGE_BACKEND=assets-s3
PENPOT_STORAGE_ASSETS_S3_ENDPOINT=https://s3.yourdomain.com
PENPOT_STORAGE_ASSETS_S3_BUCKET=penpot-assets
PENPOT_STORAGE_ASSETS_S3_ACCESS_KEY=your-access-key
PENPOT_STORAGE_ASSETS_S3_SECRET_KEY=your-secret-key
PENPOT_STORAGE_ASSETS_S3_REGION=us-east-1
八、从 Figma 迁移——实用指南
8.1 使用 Figma 导出插件
Penpot 提供了官方的 Figma 导出插件(penpot/penpot-exporter-figma-plugin),可以将 Figma 文件转换为 Penpot 格式:
# 插件安装(在 Figma 中通过 Plugin Manager 安装)
# 搜索 "Penpot Exporter" → 安装
# 导出步骤:
# 1. 在 Figma 中打开要迁移的文件
# 2. Plugins → Penpot Exporter → Export
# 3. 插件会生成 .penpot 格式的文件
# 4. 在 Penpot 中导入该文件
8.2 迁移注意事项
- Canvas 效果:Figma 的复杂阴影和混合模式可能在 SVG 中有细微差异
- 组件变体:Figma 的 Variants 与 Penpot 的变体系统映射关系需要手动验证
- Auto Layout:Figma 的 Auto Layout 与 Penpot 的 Flex 布局高度兼容,大部分可以自动转换
- 团队库:需要单独迁移,建议先迁移基础组件,再迁移复合组件
- Prototyping:交互链接和动画需要重新设置,无法自动迁移
九、与传统方案的对比
| 维度 | Penpot | Figma | Sketch + Abstract |
|---|---|---|---|
| 开源 | ✅ MPL-2.0 | ❌ 闭源 | ❌ 闭源 |
| 自托管 | ✅ 原生支持 | ❌ 云端 only | ❌ 需 Abstract |
| 渲染引擎 | SVG(W3C 标准) | Canvas(自定义) | 原生 macOS |
| Design Tokens | ✅ 原生支持 | ⚠️ 需插件 | ⚠️ 需 Abstract |
| AI/MCP 集成 | ✅ 原生支持 | ⚠️ 第三方 | ❌ 不支持 |
| 数据主权 | ✅ 完全可控 | ❌ 数据在 Figma | ⚠️ 取决于 Abstract |
| 实时协作 | ✅ WebSocket | ✅ WebSocket | ⚠️ 需 Abstract |
| 定价 | 免费(自托管成本) | $15-75/人/月 | $99/人 + Abstract |
| 开发者集成 | ✅ REST API + Webhook + MCP | ✅ REST API + Plugin | ⚠️ 有限 |
| 平台 | Web(任何浏览器) | Web + 桌面 | macOS only |
十、总结与展望
Penpot 在 2026 年已经从一个「Figma 的开源替代品」进化为一个设计与代码协作的完整平台。它的几个关键优势:
技术架构独特性:Clojure + SVG 的技术组合在同类产品中独一无二,STM 提供了优雅的并发处理,SVG 渲染降低了维护成本。
Design Tokens 原生支持:不是通过插件添加的功能,而是平台的一等公民。数学函数、JSON 导出、与 CI/CD 集成——这是一个成熟的设计系统基础设施。
AI 工作流集成:MCP 协议让 AI Agent 能直接读取设计文件和 Design Tokens,Token-Aware Prompting 方法论提供了高效的人机协作模式。
数据主权:对于有合规要求的团队(金融、医疗、政府),自托管意味着设计资产不需要离开自己的基础设施。
未来展望:
- Penpot 正在开发实时多人编辑的 CRDT 支持,这将使离线编辑和冲突解决更加健壮
- WebAssembly 加速渲染正在实验中,有望解决 SVG 大文件的性能瓶颈
- 插件系统的完善将进一步扩展生态(目前已有 Figma 导出插件,未来可能支持 VS Code 插件直接在编辑器中预览设计稿)
对于程序员来说,Penpot 值得关注的核心理由是:它不只是一个设计工具,它是一个可以用代码思维理解和操作的设计平台。Design Tokens 是 JSON,组件结构是树形对象,API 是 RESTful,集成协议是 MCP——一切都是程序员熟悉的范式。
当你需要在项目中引入设计协作能力,或者正在考虑从 Figma 迁移,Penpot 是 2026 年最值得认真评估的选择。
参考资料
- Penpot 官方文档:https://penpot.app
- Penpot GitHub 仓库:https://github.com/penpot/penpot
- Penpot AI 白皮书:https://penpot.app/blog/penpot-ai-whitepaper/
- Design Tokens 完全指南:https://penpot.app/blog/what-are-design-tokens-a-complete-guide/
- Penpot MCP 集成指南:https://penpot.app/blog/set-up-penpot-mcp-with-cursor-in-5-steps-and-no-code/
- Penpot API 与 Webhook:https://penpot.app/blog/how-to-integrate-penpot-with-your-developer-toolchain-apis-and-webhooks-for-workflow-automation/