From 4c7863d6c85ae1456ff8ad5f92835ad7109bde93 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 20 Jul 2026 14:45:59 +0200 Subject: [PATCH] :books: Add .penpot format docs and inspector tool (#10674) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * :books: Add comprehensive documentation for .penpot file format (v3) Create user-facing documentation for the .penpot binfile format to help developers and power users understand and inspect the ZIP+JSON structure. - Add technical specification with complete schema reference for all JSON files (manifest, file metadata, pages, shapes, library assets, storage objects, plugin data) - Add user-friendly overview explaining the format structure, inspection methods, and version history - Update export-import-files.njk to clarify current format is not deprecated and note that v2 was never released - Add cross-links between documentation pages - Include source code references to authoritative malli schemas AI-assisted-by: qwen3.7-plus * :paperclip: Add playwright dependency to the root package.json * :books: Add browser based .penpot file inspector to docs Add a client-side, no-build inspector for .penpot (v3) files. The tool runs entirely in the browser: JSZip is loaded lazily from a CDN, the file is never uploaded. It provides a collapsible file tree, syntax- highlighted JSON viewer with search, image previews, a summary panel with file/shape/storage counts, shape summary cards with color swatches, and clickable UUID cross-references with backlinks. The inspector is added at docs/technical-guide/developer/data-model/penpot-file-inspector.njk and linked from the format spec and the user-facing format page. AI-assisted-by: minimax-m3 * :books: Use full page width and 2-column layout for inspector The inspector previously sat inside the docs site's 42rem content column, which forced a stacked layout and wasted the wide viewport. - Hide the docs page-navigation sidebar on this page via :has() - Use a 2-column CSS grid: file tree (280px, sticky) on the left, content (flex: 1) on the right - Restore the directory tree as a permanent left-rail navigation (it was removed when the picker was first introduced, then added back as a collapsible panel; a sticky rail is a better fit now that horizontal space is plentiful) - Remove the tree toggle button — the tree is always visible - Collapses to 1 column on viewports below 900px AI-assisted-by: minimax-m3 * :lipstick: Indent nested JSON values in inspector The JSON tree view in the inspector was rendering all properties at the same indent level, making it hard to see which values were nested inside objects or arrays. Root-level properties and deeply nested ones looked identical. Add padding-left and a subtle vertical guide line to .jchildren so each nesting level is visually distinct. Bump the toggle column to 1.2em and add a touch of vertical padding to .jrow for breathing room. AI-assisted-by: minimax-m3 --- .../data-model/penpot-file-format.md | 628 ++++++++ .../data-model/penpot-file-inspector.njk | 1401 +++++++++++++++++ .../export-import/export-import-files.njk | 9 +- docs/user-guide/export-import/index.njk | 8 +- .../export-import/penpot-file-format.njk | 155 ++ package.json | 6 +- pnpm-lock.yaml | 195 +-- 7 files changed, 2272 insertions(+), 130 deletions(-) create mode 100644 docs/technical-guide/developer/data-model/penpot-file-format.md create mode 100644 docs/technical-guide/developer/data-model/penpot-file-inspector.njk create mode 100644 docs/user-guide/export-import/penpot-file-format.njk diff --git a/docs/technical-guide/developer/data-model/penpot-file-format.md b/docs/technical-guide/developer/data-model/penpot-file-format.md new file mode 100644 index 0000000000..431dbffaa2 --- /dev/null +++ b/docs/technical-guide/developer/data-model/penpot-file-format.md @@ -0,0 +1,628 @@ +--- +title: 3.02.01. Penpot file format (.penpot) +desc: Complete technical specification for the .penpot file format, including structure, schemas, and inspection methods. +--- + +# Penpot File Format (.penpot) + +The `.penpot` file format is Penpot's native export format for design files. It's a ZIP archive containing JSON metadata and binary assets, designed to be open, inspectable, and efficient. + +## Overview + +The `.penpot` format (version 3) uses a ZIP container with JSON files for metadata and binary files for media assets. This approach provides several advantages: + +- **Open and inspectable**: All metadata is human-readable JSON +- **Efficient**: ZIP compression reduces file size +- **Interoperable**: Standard formats enable third-party tooling +- **Versioned**: Clear versioning system for format and data evolution + +## Version History + +| Version | Description | Status | +|---------|-------------|--------| +| v1 | Custom binary format | Deprecated | +| v2 | SQLite-based format | Never released (internal only) | +| v3 | ZIP + JSON format | **Current** | + +## File Structure + +A `.penpot` file contains the following structure: + +``` +pencil.penpot (ZIP archive) +├── manifest.json # Root metadata +├── files/ +│ ├── {file-id}.json # File metadata +│ └── {file-id}/ +│ ├── pages/ +│ │ ├── {page-id}.json # Page metadata +│ │ └── {page-id}/ +│ │ └── {shape-id}.json # Individual shapes +│ ├── media/ +│ │ └── {media-id}.json # Media references +│ ├── colors/ +│ │ └── {color-id}.json # Library colors +│ ├── components/ +│ │ └── {component-id}.json # Library components +│ ├── typographies/ +│ │ └── {typography-id}.json # Library typographies +│ ├── tokens.json # Design tokens library +│ └── thumbnails/ +│ └── {tag}/{page-id}/{frame-id}.json # Thumbnail metadata +└── objects/ + ├── {uuid}.json # Storage object metadata + └── {uuid}.{ext} # Binary media files (png, jpg, etc.) +``` + +## Manifest Specification + +The `manifest.json` file is the root of the archive and contains metadata about the export. + +### Schema + +```json +{ + "version": 1, + "type": "penpot/export-files", + "generatedBy": "penpot/2.12.0", + "refer": "penpot", + "files": [ + { + "id": "uuid", + "name": "File Name", + "features": ["feature1", "feature2"] + } + ], + "relations": [] +} +``` + +### Fields + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `version` | integer | Yes | Format version (currently `1`) | +| `type` | string | Yes | Must be `"penpot/export-files"` | +| `generatedBy` | string | No | Penpot version that created the file | +| `refer` | string | No | Source system (typically `"penpot"`) | +| `files` | array | Yes | List of files in the archive | +| `files[].id` | UUID | Yes | File identifier | +| `files[].name` | string | Yes | File name | +| `files[].features` | array | Yes | Set of feature flags | +| `relations` | array | No | Library relationships `[file-id, library-id]` | + +### Example + +```json +{ + "type": "penpot/export-files", + "version": 1, + "generatedBy": "penpot/2.12.0-RC1-99-g40c27591f", + "refer": "penpot", + "files": [ + { + "id": "73b59a94-3ea3-8189-8007-3d36adc8c3e3", + "name": "Pencil | Penpot Design System", + "features": [ + "fdata/path-data", + "design-tokens/v1", + "variants/v1", + "layout/grid", + "components/v2", + "fdata/shape-data-type" + ] + } + ], + "relations": [] +} +``` + +## File Metadata + +Each file has a JSON file at `files/{file-id}.json` containing the file's metadata. + +### Schema + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `id` | UUID | Yes | File identifier | +| `name` | string | Yes | File name | +| `revn` | integer | Yes | Revision number | +| `vern` | integer | No | Version number | +| `createdAt` | timestamp | Yes | Creation timestamp | +| `modifiedAt` | timestamp | Yes | Last modification timestamp | +| `deletedAt` | timestamp | No | Deletion timestamp (if soft-deleted) | +| `projectId` | UUID | No | Project identifier | +| `teamId` | UUID | No | Team identifier | +| `isShared` | boolean | No | Whether file is a shared library | +| `hasMediaTrimmed` | boolean | No | Whether media has been trimmed | +| `features` | array | Yes | Set of enabled feature flags | +| `migrations` | array | No | List of applied data migrations | +| `options` | object | No | File-level options | + +### Features + +The `features` field is a set of strings indicating which features are enabled in the file. Common features include: + +| Feature | Description | +|---------|-------------| +| `fdata/path-data` | Path data format | +| `fdata/shape-data-type` | Shape data type system | +| `design-tokens/v1` | Design tokens support | +| `variants/v1` | Component variants | +| `layout/grid` | Grid layout system | +| `components/v2` | Component system v2 | +| `plugins/runtime` | Plugin runtime support | + +### Migrations + +The `migrations` field lists all data migrations applied to the file. This ensures backward compatibility when the data model evolves. + +### Example + +```json +{ + "id": "73b59a94-3ea3-8189-8007-3d36adc8c3e3", + "name": "Pencil | Penpot Design System", + "revn": 28425, + "vern": 0, + "createdAt": "2025-12-10T10:24:18.686066Z", + "modifiedAt": "2025-12-10T12:13:49.799076Z", + "teamId": "b62e1aa4-d9a7-8147-8005-2813bed4056e", + "projectId": "f23add0e-6b77-8069-8005-41b48b93a5da", + "isShared": true, + "features": [ + "fdata/path-data", + "design-tokens/v1", + "variants/v1", + "layout/grid", + "components/v2", + "fdata/shape-data-type" + ], + "migrations": [ + "legacy-2", + "legacy-3", + "0001-remove-tokens-from-groups", + "0002-normalize-bool-content-v2" + ], + "options": { + "componentsV2": true + } +} +``` + +## Pages and Shapes + +### Page Structure + +Each page is stored at `files/{file-id}/pages/{page-id}.json`. + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `id` | UUID | Yes | Page identifier | +| `name` | string | Yes | Page name | +| `index` | integer | No | Page order in the file | +| `options` | object | No | Page options (guides, etc.) | +| `background` | string | No | Background color (hex) | +| `flows` | object | No | Prototype flows | +| `guides` | object | No | Ruler guides | + +### Shapes + +Individual shapes are stored at `files/{file-id}/pages/{page-id}/{shape-id}.json`. + +#### Shape Types + +Penpot supports 9 shape types: + +| Type | Description | +|------|-------------| +| `frame` | Container frame (artboard) | +| `group` | Group of shapes | +| `rect` | Rectangle | +| `circle` | Circle/Ellipse | +| `path` | Vector path | +| `text` | Text shape | +| `image` | Image | +| `bool` | Boolean operation | +| `svg-raw` | Raw SVG element | + +#### Base Shape Attributes + +All shapes share these base attributes: + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `id` | UUID | Yes | Shape identifier | +| `name` | string | Yes | Shape name | +| `type` | string | Yes | Shape type (see above) | +| `selrect` | object | Yes | Selection rectangle `{x, y, width, height}` | +| `points` | array | Yes | Array of points `[{x, y}, ...]` | +| `transform` | array | Yes | 2D transformation matrix | +| `transformInverse` | array | Yes | Inverse transformation matrix | +| `parentId` | UUID | Yes | Parent shape identifier | +| `frameId` | UUID | Yes | Containing frame identifier | + +#### Geometry Attributes + +Shapes with geometry (frame, rect, circle, image, svg-raw, text): + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `x` | number | Yes | X position | +| `y` | number | Yes | Y position | +| `width` | number | Yes | Width | +| `height` | number | Yes | Height | + +#### Generic Attributes + +Optional attributes available on all shapes: + +| Field | Type | Description | +|-------|------|-------------| +| `fills` | array | Fill styles | +| `strokes` | array | Stroke styles | +| `opacity` | number | Opacity (0-1) | +| `blendMode` | string | Blend mode | +| `shadow` | array | Shadow effects | +| `blur` | object | Blur effect | +| `constraintsH` | string | Horizontal constraint | +| `constraintsV` | string | Vertical constraint | +| `r1`, `r2`, `r3`, `r4` | number | Border radius corners | +| `blocked` | boolean | Shape is locked | +| `hidden` | boolean | Shape is hidden | +| `collapsed` | boolean | Shape is collapsed | +| `componentId` | UUID | Component reference | +| `componentFile` | UUID | Component library file | +| `shapeRef` | UUID | Shape reference for components | +| `touched` | array | Modified component properties | +| `interactions` | array | Prototype interactions | +| `exports` | array | Export settings | +| `grids` | array | Grid configurations | +| `appliedTokens` | object | Applied design tokens | +| `pluginData` | object | Plugin-specific data | + +#### Type-Specific Attributes + +**Frame** +- `shapes`: array of child shape UUIDs +- `showContent`: boolean +- `hideInViewer`: boolean + +**Group** +- `shapes`: array of child shape UUIDs + +**Bool** +- `shapes`: array of child shape UUIDs +- `boolType`: string (`union`, `difference`, `exclude`, `intersection`) +- `content`: path data + +**Path** +- `content`: path data (SVG path commands) + +**Text** +- `content`: text content with formatting +- `positionData`: glyph position data + +**Image** +- `metadata`: object with `width`, `height`, `mtype`, `id` + +### Example Shape + +```json +{ + "id": "260aea33-4e55-808c-8007-3d4f2efe4230", + "name": "Rectangle", + "type": "rect", + "x": 100, + "y": 100, + "width": 200, + "height": 150, + "selrect": { + "x": 100, + "y": 100, + "width": 200, + "height": 150 + }, + "points": [ + {"x": 100, "y": 100}, + {"x": 300, "y": 100}, + {"x": 300, "y": 250}, + {"x": 100, "y": 250} + ], + "transform": [1, 0, 0, 1, 0, 0], + "transformInverse": [1, 0, 0, 1, 0, 0], + "parentId": "00000000-0000-0000-0000-000000000000", + "frameId": "00000000-0000-0000-0000-000000000001", + "fills": [ + { + "color": "#FF5733", + "opacity": 1 + } + ], + "r1": 8, + "r2": 8, + "r3": 8, + "r4": 8 +} +``` + +## Library Assets + +### Colors + +Stored at `files/{file-id}/colors/{color-id}.json`. + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `id` | UUID | Yes | Color identifier | +| `name` | string | Yes | Color name | +| `path` | string | No | Path in the library tree | +| `opacity` | number | No | Opacity (0-1) | +| `color` | string | Conditional | Hex color (for plain colors) | +| `gradient` | object | Conditional | Gradient definition | +| `image` | object | Conditional | Image fill definition | + +#### Plain Color Example + +```json +{ + "id": "abc123...", + "name": "Primary Blue", + "path": "Brand/Primary", + "color": "#0066CC", + "opacity": 1 +} +``` + +#### Gradient Color Example + +```json +{ + "id": "def456...", + "name": "Sunset Gradient", + "gradient": { + "type": "linear", + "startX": 0, + "startY": 0, + "endX": 1, + "endY": 1, + "stops": [ + {"color": "#FF6B6B", "offset": 0, "opacity": 1}, + {"color": "#4ECDC4", "offset": 1, "opacity": 1} + ] + } +} +``` + +### Components + +Stored at `files/{file-id}/components/{component-id}.json`. + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `id` | UUID | Yes | Component identifier | +| `name` | string | Yes | Component name | +| `path` | string | Yes | Path in the library tree | +| `mainInstanceId` | UUID | Yes | Root shape of main instance | +| `mainInstancePage` | UUID | Yes | Page containing main instance | +| `modifiedAt` | timestamp | No | Last modification | +| `objects` | object | No | Captured shapes (if deleted) | + +### Typographies + +Stored at `files/{file-id}/typographies/{typography-id}.json`. + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `id` | UUID | Yes | Typography identifier | +| `name` | string | Yes | Typography name | +| `fontId` | string | Yes | Font identifier | +| `fontFamily` | string | Yes | Font family name | +| `fontVariantId` | string | Yes | Font variant | +| `fontSize` | string | Yes | Font size | +| `fontWeight` | string | Yes | Font weight | +| `fontStyle` | string | Yes | Font style | +| `lineHeight` | string | Yes | Line height | +| `letterSpacing` | string | Yes | Letter spacing | +| `textTransform` | string | Yes | Text transform | + +### Design Tokens + +Stored at `files/{file-id}/tokens.json`. + +The tokens library contains: + +- **Sets**: Collections of tokens organized hierarchically +- **Themes**: Named combinations of token sets +- **Active Themes**: Currently applied themes + +#### Token Structure + +```json +{ + "sets": { + "core": { + "id": "uuid", + "name": "Core", + "tokens": { + "color": { + "primary": { + "id": "uuid", + "name": "primary", + "type": "color", + "value": "#0066CC" + } + } + } + } + }, + "themes": { + "light": { + "id": "uuid", + "name": "Light", + "sets": ["core"] + } + }, + "activeThemes": ["light"] +} +``` + +## Media and Storage Objects + +### Storage Objects + +Binary assets (images, fonts, etc.) are stored in the `objects/` directory. + +Each storage object has: +- `objects/{uuid}.json` - Metadata +- `objects/{uuid}.{ext}` - Binary content (png, jpg, svg, etc.) + +#### Metadata Schema + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `id` | UUID | Yes | Storage object identifier | +| `size` | integer | Yes | File size in bytes | +| `contentType` | string | Yes | MIME type | +| `bucket` | string | Yes | Storage bucket | +| `hash` | string | No | Content hash (blake2b) | + +#### Example + +```json +{ + "id": "0039433d-adc8-430d-b2c3-d884dea6e050", + "size": 575, + "contentType": "image/png", + "bucket": "file-media-object", + "hash": "blake2b:77d447db38eb5daf31acb7344a504cacc6b79aa11855a00501d9475c595053d0" +} +``` + +### Media References + +File media references are stored at `files/{file-id}/media/{media-id}.json`. + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `id` | UUID | Yes | Media identifier | +| `name` | string | Yes | File name | +| `width` | integer | Yes | Image width | +| `height` | integer | Yes | Image height | +| `mtype` | string | Yes | MIME type | +| `mediaId` | UUID | Yes | Reference to storage object | +| `thumbnaillId` | UUID | No | Reference to thumbnail | +| `isLocal` | boolean | No | Whether media is local to file | + +### Thumbnails + +Page thumbnails are stored at `files/{file-id}/thumbnails/{tag}/{page-id}/{frame-id}.json`. + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `fileId` | UUID | Yes | File identifier | +| `pageId` | UUID | Yes | Page identifier | +| `frameId` | UUID | Yes | Frame identifier | +| `tag` | string | Yes | Thumbnail tag | +| `mediaId` | UUID | Yes | Reference to storage object | + +## Plugin Data + +Plugins can store custom data on files, pages, shapes, components, colors, and typographies using the `pluginData` field. + +### Structure + +```json +{ + "pluginData": { + "plugin-id": { + "key1": "value1", + "key2": "value2" + } + } +} +``` + +The plugin ID is a keyword (e.g., `"my-plugin"`), and the values are string key-value pairs. + +## Inspecting a .penpot File + +### List Contents + +```bash +unzip -l design.penpot +``` + +### Extract and View + +```bash +# Extract to temporary directory +unzip design.penpot -d /tmp/penpot-inspect + +# View manifest +cat /tmp/penpot-inspect/manifest.json | jq . + +# List all files +find /tmp/penpot-inspect -name "*.json" | head -20 + +# View a specific shape +cat /tmp/penpot-inspect/files/*/pages/*/*.json | jq . +``` + +### Browser-Based Inspector + +For an interactive way to explore a `.penpot` file, try the [**Penpot file inspector**](/technical-guide/developer/data-model/penpot-file-inspector/). It runs entirely in your browser, displays a collapsible file tree, syntax-highlighted JSON, image previews, and clickable cross-references between shapes, components, colors, and media. + +### Quick Inspection Script + +```bash +#!/bin/bash +# Inspect .penpot file structure + +FILE=$1 +TMPDIR=$(mktemp -d) + +unzip -q "$FILE" -d "$TMPDIR" + +echo "=== Manifest ===" +cat "$TMPDIR/manifest.json" | jq '{type, version, files: [.files[] | {id, name}]}' + +echo -e "\n=== Files ===" +for f in "$TMPDIR"/files/*.json; do + echo "- $(jq -r '.name' "$f")" +done + +echo -e "\n=== Pages ===" +for f in "$TMPDIR"/files/*/pages/*.json; do + echo "- $(jq -r '.name' "$f")" +done + +echo -e "\n=== Storage Objects ===" +ls -lh "$TMPDIR"/objects/*.{png,jpg,svg} 2>/dev/null | wc -l +echo "media files" + +rm -rf "$TMPDIR" +``` + +## Cross-References + +- [Penpot file inspector](/technical-guide/developer/data-model/penpot-file-inspector/) - Browser-based interactive inspector +- [Data Model](/technical-guide/developer/data-model/) - Conceptual data model +- [Data Guide](/technical-guide/developer/data-guide/) - Working with data structures +- [Export/Import Files](/user-guide/export-import/export-import-files/) - User guide for exporting and importing + +## Source Code References + +The authoritative schema definitions are in the Penpot source code: + +- **Manifest**: `backend/src/app/binfile/v3.clj` (schema:manifest) +- **File**: `common/src/app/common/types/file.cljc` (schema:file) +- **Page**: `common/src/app/common/types/page.cljc` (schema:page) +- **Shape**: `common/src/app/common/types/shape.cljc` (schema:shape) +- **Component**: `common/src/app/common/types/component.cljc` (schema:component) +- **Color**: `common/src/app/common/types/color.cljc` (schema:library-color) +- **Typography**: `common/src/app/common/types/typography.cljc` (schema:typography) +- **Tokens**: `common/src/app/common/types/tokens_lib.cljc` (schema:tokens-lib) +- **Plugin Data**: `common/src/app/common/types/plugins.cljc` (schema:plugin-data) +- **Features**: `common/src/app/common/features.cljc` (schema:features) diff --git a/docs/technical-guide/developer/data-model/penpot-file-inspector.njk b/docs/technical-guide/developer/data-model/penpot-file-inspector.njk new file mode 100644 index 0000000000..5321f79fe0 --- /dev/null +++ b/docs/technical-guide/developer/data-model/penpot-file-inspector.njk @@ -0,0 +1,1401 @@ +--- +title: 3.02.02. Penpot file inspector +desc: Interactive browser-based inspector for .penpot (v3) files. Upload a file to explore its ZIP structure, browse JSON contents, preview images, and navigate cross-references. +--- + + + +

Penpot file inspector

+ +

Upload a .penpot file to explore its contents. The inspector runs entirely in your browser — your file is never uploaded to a server.

+ +
+ +
+ + +
+ +

How it works

+ +

This tool is a static page with no backend. When you upload a file, the browser:

+ +
    +
  1. Reads the file as a ZIP archive using JSZip (loaded lazily from a CDN on first use).
  2. +
  3. Parses the manifest, file metadata, and structure to build an overview.
  4. +
  5. Lets you navigate the file tree, view JSON contents with syntax highlighting, preview embedded images, and click through cross-references (UUIDs).
  6. +
+ +

For full details on the file format, see the complete technical specification.

+ +

Privacy

+ +

Your file is processed entirely in your browser. Nothing is uploaded to any server. The only network request the page makes is fetching the JSZip library from cdn.jsdelivr.net on the first file upload.

+ + diff --git a/docs/user-guide/export-import/export-import-files.njk b/docs/user-guide/export-import/export-import-files.njk index e916fd6304..ac462d64cf 100644 --- a/docs/user-guide/export-import/export-import-files.njk +++ b/docs/user-guide/export-import/export-import-files.njk @@ -48,21 +48,22 @@ desc: Learn how to import and export files in Penpot, the free, open-source desi
Import penpot file

Penpot file format

-

Penpot export to a unique format that streamline the import and export of files and assets by being more efficient and interoperable.

+

Penpot exports to a unique format that streamlines the import and export of files and assets by being more efficient and interoperable.

Unlike other design tools, Penpot's format is built on standard languages. The exported file is essentially a ZIP archive containing binary assets (such as bitmap and vector images) alongside a readable JSON structure. By avoiding proprietary formats, Penpot empowers users with autonomy from specific tools while enabling seamless third-party integrations.

+

For a detailed look at what's inside a .penpot file, see The .penpot file format. Developers can also check the technical specification.

Deprecated Penpot file formats

These formats can only be exported from version 2.3 or earlier versions, but can be imported to any Penpot version.

There are two different deprecated Penpot file formats in which you can import/export Penpot files. A standard one and a binary one. You always have the chance to use both for any file.

-

[Deprecated] Penpot file (.penpot).

+

[Deprecated] Binary file (.penpot) — v1

The fast one. Binary Penpot specific.

-

[Deprecated] Standard file (.zip).

-

The open one. A compressed file that includes SVG and JSON.

+

[Deprecated] Standard file (.zip) — v2 (never released)

+

The open one. A compressed file that includes SVG and JSON. This format was developed but never released to users.