DEV Community

Cover image for Open Source Project #101: Penpot — The Open-Source Design Tool That Speaks CSS Natively
WonderLab
WonderLab

Posted on

Open Source Project #101: Penpot — The Open-Source Design Tool That Speaks CSS Natively

Introduction

"Figma's problem isn't that it lacks features. It's that your design data isn't yours, and there's a permanent translation layer between designers and developers."

This is article #101 in the "One Open Source Project a Day" series. Today's project is Penpot — an open-source design and prototyping collaboration tool built with a full Clojure/ClojureScript stack.

In 2022, Adobe announced a $20B acquisition of Figma, and the design community started having a serious conversation about open-source alternatives. Penpot saw significant growth after that announcement, but its core thesis was established long before — when Kaleidos originally built it: design tools should be open, design data should be in standard formats, and there should be no translation layer between design and development.

Three "should be" statements, backed by three real engineering decisions: MPL-2.0 license + Docker self-hosting, SVG as the native storage format, and design properties that map directly to CSS (Grid, Flex, typography, spacing).

What You'll Learn

  • What SVG-native format actually means, and why it's the key to eliminating the design-dev gap
  • CSS-mapped design properties: how Grid/Flex layout tools align with CSS
  • The engineering logic behind choosing Clojure/ClojureScript for the full stack
  • Docker Compose self-hosting deployment structure
  • Real-time collaboration via WebSocket architecture
  • Full design system support: components, color palettes, text styles
  • The fundamental difference from Figma — not a feature comparison, a philosophy comparison

Prerequisites

  • Experience with design tools (Figma, Sketch, or similar)
  • Basic understanding of SVG format
  • Basic familiarity with CSS Flexbox and Grid

Project Background

Overview

Penpot is a web-based open-source design and prototyping collaboration platform, built as an open-source alternative to Figma and Sketch. Its core technical decisions are: SVG as the native storage format, and design properties aligned with CSS specifications.

What those decisions mean in practice:

  1. Exported design files are standard SVG, openable in any SVG-capable tool
  2. The Flex layout, Grid layout, and spacing properties a designer configures in Penpot speak the same language as what a developer writes in CSS

The "translation work" between designers and developers (manually converting Figma's constraint system into CSS values) is substantially eliminated by this architecture.

The project was created by Kaleidos, a Spanish digital product studio, and is now maintained by the Penpot team with both a managed cloud option (penpot.app) and a self-hostable community edition.

Author / Team

  • Organization: Kaleidos / Penpot Team
  • Tech Stack: Clojure (backend) + ClojureScript (frontend) + PostgreSQL
  • License: Mozilla Public License 2.0 (MPL-2.0)
  • Website: penpot.app

Project Stats

  • ⭐ GitHub Stars: 35,000+
  • 🍴 Forks: 1,700+
  • 📄 License: MPL-2.0
  • 🌐 Active community with multilingual contributions

Features

What It Does

Traditional design toolchain (Figma pattern):
Designer works in Figma
    ↓
Export PNG/PDF or use Figma Dev Mode
    ↓
Developer manually reads: font sizes, colors, spacing, flex alignment...
    ↓
Rewrites everything in CSS

Penpot pattern:
Designer works in Penpot (properties are already CSS concepts)
    ↓
Developer inspects the panel and sees CSS Grid/Flex properties directly
    ↓
Copy CSS snippets or understand style rules immediately
Enter fullscreen mode Exit fullscreen mode

Use Cases

  1. Team design collaboration: Multiple people editing the same file in real time, no Figma subscription required — ideal for budget-conscious teams or those with strict data security requirements
  2. Enterprise private deployment: Finance, healthcare, and other industries with data sovereignty requirements can run Penpot on-premises via Docker in a private network
  3. Design system management: Component libraries, color palettes, text styles, icon sets — organizing design standards
  4. Interactive prototyping: Add transition animations and interaction flows, produce clickable prototypes
  5. Design-development handoff: CSS-native properties let frontend developers read design intent directly, reducing back-and-forth communication
  6. Open source project design assets: Design files can be open-sourced, collaborated on, and version-controlled like code

Quick Start

Docker Compose self-hosting (recommended):

# Download the official docker-compose config
wget https://raw.githubusercontent.com/penpot/penpot/main/docker/images/docker-compose.yaml

# Start (includes backend, frontend, PostgreSQL, Redis, mail service)
docker compose -p penpot -f docker-compose.yaml up -d
Enter fullscreen mode Exit fullscreen mode

Visit http://localhost:9001. The first registered account becomes the administrator.

Key environment variables:

# Critical settings in docker-compose.yaml
PENPOT_FLAGS=enable-registration enable-login-with-password
PENPOT_DATABASE_URI=postgresql://penpot/penpot
PENPOT_REDIS_URI=redis://redis/0

# Object storage (optional, defaults to local filesystem)
PENPOT_STORAGE_BACKEND=s3
PENPOT_STORAGE_S3_BUCKET=your-bucket
Enter fullscreen mode Exit fullscreen mode

Upgrading:

docker compose -p penpot -f docker-compose.yaml pull
docker compose -p penpot -f docker-compose.yaml up -d
Enter fullscreen mode Exit fullscreen mode

Core Features

SVG-Native Format

Penpot's file format is essentially structured SVG. This means:

  • No proprietary binary format exists
  • Design files can be read by any SVG parser
  • Exports are standard format with no dedicated export plugins needed

CSS-Aligned Design Properties

In Penpot, when you configure a container's layout, the concepts map one-to-one with CSS:

Penpot Layout Panel          ↔    CSS Equivalent
──────────────────────────────────────────────────
Flex direction: Row           ↔    flex-direction: row
Main axis: Space Between      ↔    justify-content: space-between
Cross axis: Center            ↔    align-items: center
Row gap: 16px                 ↔    row-gap: 16px
Padding: 12px                 ↔    padding: 12px
Enter fullscreen mode Exit fullscreen mode

Grid layout follows the same pattern — Penpot's Grid tool directly exposes grid-template-columns, grid-template-rows, gap, and other CSS Grid concepts.

Design System Support

  • Components: Create a Main Component, copy it anywhere in the file as an Instance; modify the main component and all instances update automatically
  • Component overrides: Instances can override specific properties (text, color) while preserving the component structure
  • Shared libraries: Share one file's asset library (components, palettes, text styles, icons) with other files in the team
  • Color system: Project-level and file-level color palettes with color variable support
  • Text styles: Define named text styles (H1, Body, Caption), reuse across files

Real-time Collaboration

Multiple people editing the same file simultaneously:

  • User cursors visible in real time (shows where other collaborators are working)
  • Comment system (add pinned comments on the design, @-mention teammates)
  • Version history (revert to any prior version)
  • File permissions (viewer / editor roles)

Deep Dive

Clojure/ClojureScript Full Stack

Penpot is one of the rare large-scale open-source projects that uses Clojure across the entire stack in production.

Backend: Clojure (JVM)
    ├── HTTP API (RESTful)
    ├── WebSocket real-time collaboration handler
    ├── File storage management
    └── PostgreSQL data access

Frontend: ClojureScript (compiled to JavaScript)
    ├── React-based UI rendering (rum library)
    ├── Canvas rendering (SVG-based)
    ├── State management (immutable data structures)
    └── WebSocket client (real-time sync)

Database: PostgreSQL
    ├── Users, teams, projects
    └── Design file metadata

Redis:
    └── Session management, real-time collaboration state
Enter fullscreen mode Exit fullscreen mode

The engineering rationale for choosing Clojure/ClojureScript:

  • Isomorphic data sharing: Frontend and backend use the same data structures to describe design files, reducing serialization friction
  • Immutable data structures: Native support for Undo/Redo history — each operation produces a new state, old states are automatically preserved
  • Functional programming: Complex graphic transformations (matrix operations, path operations) expressed as pure functions, easier to test and reason about

SVG Data Model

Penpot's design files are represented internally as a tree data structure, where each element maps to an SVG node:

;; Internal representation of a rectangle element (simplified)
{:type :rect
 :id "uuid-xxx"
 :name "Button Background"
 :x 100, :y 200
 :width 200, :height 48
 :fill [{:fill-color "#3355FF" :fill-opacity 1}]
 :r1 8 :r2 8 :r3 8 :r4 8  ; border-radius
 :layout-item-margin {:m1 0 :m2 16 :m3 0 :m4 16}  ; margin in parent Flex container
}
Enter fullscreen mode Exit fullscreen mode

This data structure can be serialized directly to SVG attributes, with no second-pass conversion from "design software internal format → export format."

Real-time Collaboration Architecture

Client A (designer)
    │  Move element operation
    ▼
WebSocket connection
    │  Send operation (Transaction)
    ▼
Backend WebSocket handler
    │
    ├── Persist to PostgreSQL
    │
    ├── Broadcast to other clients in the same file
    │
    └── Client B (another designer) receives → applies operation → updates local state
Enter fullscreen mode Exit fullscreen mode

Operations are described as "operation type + parameters" rather than sending the complete file — incremental changes are transmitted (similar in spirit to CRDT, but simpler in implementation).

Prototype Interaction System

Penpot's prototype interactions are based on a Frame → Frame navigation model:

Page Frame A (login page)
    │  Click "Sign In" button
    │  Trigger: click
    │  Animation: slide in (right→left, 300ms)
    ▼
Page Frame B (home page)
Enter fullscreen mode Exit fullscreen mode

Supported triggers: click, hover, mouse down, mouse up, enter/leave viewport
Supported transitions: instant, dissolve, slide in, slide out, pop
Supported navigation actions: navigate to frame, overlay frame, replace frame, scroll to element

This is sufficient to represent most mobile and web product interaction flows.

Deployment Architecture

A complete Docker Compose deployment includes:

┌─────────────────────────────────────────┐
│         Nginx (reverse proxy)            │
│           localhost:9001                 │
└──────┬──────────────┬────────────────────┘
       │              │
       ▼              ▼
┌──────────┐    ┌──────────────┐
│ Frontend │    │   Backend    │
│ (static) │    │  (Clojure)  │
│  :3449   │    │    :6060     │
└──────────┘    └──────┬───────┘
                       │
         ┌─────────────┼──────────────┐
         ▼             ▼              ▼
    ┌─────────┐  ┌──────────┐  ┌──────────┐
    │Postgres │  │  Redis   │  │  Storage │
    │  :5432  │  │  :6379   │  │(local/S3)│
    └─────────┘  └──────────┘  └──────────┘
Enter fullscreen mode Exit fullscreen mode

Penpot vs. Figma: The Fundamental Differences

Dimension Penpot Figma
Data ownership Fully self-hosted; data on your servers Data on Figma/Adobe cloud
File format SVG-native; openable with standard tools Proprietary .fig format
CSS alignment Design properties directly match CSS concepts Requires Dev Mode translation
Pricing Self-hosted free; cloud has free tier Free tier limited; pro subscription
Plugin ecosystem Community plugins, smaller scale Mature, extensive plugin ecosystem
Performance Browser SVG rendering, slower on very large files Native rendering engine, better performance
Multiplayer Supported, WebSocket-based Supported, more mature
Version history Supported Supported (more feature-complete)
Technical openness Fully open source, extensible Closed source, no customization

Figma maintains advantages in plugin ecosystem breadth, rendering performance, and advanced collaboration features. Penpot's advantages are data sovereignty, developer-friendly CSS alignment, and extensibility as an open-source project.

Why SVG as Native Format Matters

Most design tools use SVG as an export format — meaning there's a lossy conversion from the internal representation to SVG. Penpot's internal representation is SVG-compatible from the start.

The practical implications:

  1. No data loss in export: What you see in the design is what you get in SVG. No rounding, no approximation, no feature loss.

  2. Accessible to any SVG tool: The design file can be read, modified, or processed by scripts, browser APIs, or other design tools without Penpot being installed.

  3. Version control friendly: SVG is text-based XML. Design files can live in git, diffs are human-readable (to a degree), and merge conflicts are theoretically resolvable.

  4. Developer hand-inspection: A developer can inspect a Penpot export in browser DevTools and see exactly what the design file says — it's the same coordinate system, the same property names.


Resources

Official Links

Related Resources

  • Docker Hub images: penpotapp/backend, penpotapp/frontend
  • Contribution guide: CONTRIBUTING.md (in the repository)

Summary

Penpot's core argument is: the problem with design tools isn't missing features — it's closed data, non-standard formats, and a permanent translation layer between design and development.

The SVG-native format and CSS-aligned property system are the direct technical answers to that argument. When a frontend developer opens Penpot's inspection panel and sees flex-direction: row, gap: 16px, border-radius: 8px — that's CSS. They can write it directly. No translation needed.

The Clojure/ClojureScript full-stack choice is an interesting engineering decision: immutable data structures support Undo/Redo natively, isomorphic data models reduce frontend/backend friction, and functional programming makes complex graphic transformations testable. These benefits are real for a design tool, which is fundamentally an interaction-intensive application with rich undo/redo requirements.

For enterprises that need data sovereignty, teams with budget constraints, or teams that care about design-development workflow integration, Penpot is currently the open-source design tool with the highest product completeness and the clearest engineering architecture.


Explore PrimeSkills — a curated marketplace of AI agents and skills, each validated against real enterprise workflows. No hype, just what actually works.

Visit my personal site for more insights and interesting products.

Top comments (0)