Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
5047fb7
feat: init
juanfran Mar 26, 2024
255920d
feat: add dependencies & update README.md
juanfran Apr 4, 2024
b3dfb94
feat: LICENSE
juanfran Apr 24, 2024
8bb77f1
feat: update manifest
juanfran May 28, 2024
d0cdaab
feat: upgrade styles & types
juanfran Jun 10, 2024
65c4701
chore: upgrade styles & types
juanfran Jul 5, 2024
ee40091
fix: updadate permissions
juanfran Jul 9, 2024
e71ab92
chore: upgrade styles & types
juanfran Jul 12, 2024
b6f1185
chore: improve docs
juanfran Jul 30, 2024
17cb85c
feat: improve initial example
juanfran Jul 30, 2024
8ccfeeb
chore: update dependencies version
cocotime Jul 31, 2024
83ee192
chore(deps): update package-lock
juanfran Aug 8, 2024
df0f300
feat: live reload
juanfran Aug 13, 2024
ffd7514
chore: switched from class selector to data attribute
cocotime Aug 30, 2024
e0fb380
chore: update readme
cocotime Sep 6, 2024
cc2e210
chore: added video to readme
cocotime Sep 6, 2024
af6749c
chore: added video to readme
cocotime Sep 6, 2024
6e1ac7f
fix: added video to readme
cocotime Sep 6, 2024
34d0b6f
chore: update url video readme
cocotime Sep 9, 2024
13c1dd6
Merge pull request #2 from penpot/marina/update/readme
cocotime Sep 9, 2024
af3e4e9
feat: update readme
mavalroot Sep 10, 2024
23b139b
Fix starter template to use the latest API
dfelinto Oct 1, 2024
91961e1
chore: replaced outdated method
cocotime Oct 3, 2024
e2767db
chore: update dependencies
cocotime Oct 4, 2024
6b0943a
Merge pull request #5 from dfelinto/patch-1
juanfran Oct 25, 2024
b47b76a
chore: update dependencies
juanfran Oct 25, 2024
af7a889
feat: updated doc links
mavalroot Oct 25, 2024
7d4377b
chore: update penpot dependencies
juanfran Jul 4, 2025
8eda696
refactor: remove unnecessary stuff
Omikorin Dec 31, 2024
5648946
fix: remove overshadowing fonts
Omikorin Dec 31, 2024
8c5748c
fix: cors
Omikorin Jul 17, 2025
705f2a6
build: bump deps
Omikorin Dec 31, 2024
ff2f791
fix: deprecated
Omikorin Dec 31, 2024
0bd6c80
build: improve developer experience
Omikorin Dec 31, 2024
bc93eae
build: bump deps
Omikorin Jul 17, 2025
5da114a
initial commit
akshay-gupta7 Feb 8, 2026
8921ec4
add list of sync providers
akshay-gupta7 Feb 8, 2026
f17d7ef
update cancel button size
akshay-gupta7 Feb 9, 2026
4139cd8
add push logic
akshay-gupta7 Feb 9, 2026
0ed5276
Add pull process
akshay-gupta7 Feb 13, 2026
f0a603f
fix pulling themes
akshay-gupta7 Feb 16, 2026
935f5ec
add selectedtokensets for active theme
akshay-gupta7 Feb 16, 2026
2af49b4
update verbose
akshay-gupta7 Feb 17, 2026
e939321
add semantic diffing for push/pull operations
akshay-gupta7 Feb 27, 2026
8dbe00e
fix pull
akshay-gupta7 Mar 2, 2026
687a960
fix diff pulling
akshay-gupta7 Mar 2, 2026
0575e0c
add commit message option
akshay-gupta7 Mar 2, 2026
6a19989
refactor
akshay-gupta7 Apr 17, 2026
7b44f2f
remove test data and UI
akshay-gupta7 Apr 17, 2026
f64885a
resolve readme conflict by keeping refactored version
akshay-gupta7 Apr 17, 2026
55e1acf
update readme.md
akshay-gupta7 Apr 17, 2026
577d4ea
remove pat
akshay-gupta7 Apr 28, 2026
08ef5ab
fix(plugin): resolve token sync validation errors and reference issues
akshay-gupta7 May 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) KALEIDOS INC

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
85 changes: 83 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,83 @@
# penpot-github-sync-plugin
A Penpot plugin that syncs design tokens stored in Penpot with files stored in GitHub repositories.
# Penpot Tokens Sync Plugin

A professional, high-quality Penpot plugin designed to bridge the gap between Penpot design tokens and developer-friendly token formats (Tokens Studio/DTCG). Sync your tokens directly with GitHub repositories for a seamless Design-to-Code workflow.

## 🚀 Purpose

This plugin serves as a "Source of Truth" connector. It allows designers using Penpot to:
1. **Sync** the tokens with a GitHub repository using Push and Pull operations.
2. **Review** semantic differences before committing or applying changes to ensure design consistency.

## ✨ Features

- **DTCG Support**: Full compatibility with the Design Tokens Community Group (DTCG) specification.
- **GitHub Integration**: Built-in support for GitHub sync using Personal Access Tokens (PAT).
- **Visual Diffing**: Review exactly what changed (Added, Modified, Removed) before applying updates.
- **Theme Management**: Support for multi-theme exports and token sets.
- **Zero Dependencies (Runtime)**: Lightweight, modular JavaScript architecture with no heavy external libraries in the plugin bundle.

## 🛠 Setup Instructions

### Prerequisites
- A Penpot account and a Penpot project.
- A GitHub account and a repository to store your tokens.
- [GitHub Personal Access Token (PAT)](https://github.com/settings/tokens) with `repo` scope.

### Installation
1. Clone this repository:
```bash
git clone https://github.com/tokens-studio/penpot-github-sync-plugin.git
cd penpot-github-sync-plugin
```
2. Install dependencies:
```bash
npm install
```
3. Start the development server:
```bash
npm run dev
```
4. In Penpot, go to **Plugins** -> **Developer** -> **Create Plugin**.
5. Set the **URL** to `http://localhost:4400/manifest.json`.
6. Open the plugin in your Penpot file.

## 🔄 GitHub Sync Functionality

### 1. Adding a Provider
Click the **+ Add Provider** button and fill in the details:
- **Name**: A label for this configuration.
- **Token**: Your GitHub PAT.
- **Repository**: The path to your repo (e.g., `owner/repo`).
- **Branch**: The branch to sync with (e.g., `main`).
- **Path**: The file path in the repo (e.g., `tokens/design-tokens.json`).

### 2. Pushing Tokens (Design -> Code)
- Click **↑ Push** next to a provider.
- The plugin extracts your Penpot tokens and compares them with the remote file.
- Review the differences in the modal.
- Enter a commit message and confirm.

### 3. Pulling Tokens (Code -> Design)
- Click **↓ Pull** next to a provider.
- The plugin fetches the remote tokens.
- Review the changes that will be applied to your Penpot file.
- Confirm to update your local sets, tokens, and themes.

## 🧪 Development

### Build for Production
To generate a production-ready bundle:
```bash
npm run build
```
The output will be in the `dist/` directory.

### Project Structure
- `src/plugin/`: Penpot API logic (runs in the Penpot environment).
- `src/ui/`: Plugin UI logic (runs in the iframe).
- `src/common/`: Shared utilities (e.g., semantic diff logic).
- `index.html`: Main UI template.
- `style.css`: Design system and component styles.

## 📄 License
MIT License. See [LICENSE](LICENSE) for details.
106 changes: 106 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Penpot Tokens Sync</title>
</head>
<body>
<!-- Main Dashboard View -->
<div id="main-view" class="view">
<header class="view-header">
<h1>Penpot Tokens Sync</h1>
<p class="subtitle">Sync your design tokens with Tokens Studio/DTCG format.</p>
</header>

<section class="sync-section">
<div class="section-header">
<h2>GitHub Sync</h2>
<button id="add-sync-btn" class="secondary-btn small">+ Add Provider</button>
</div>
<div id="providers-list" class="providers-list">
<!-- Providers will be rendered here -->
</div>
</section>
</div>

<!-- Sync Form View -->
<div id="sync-form-view" class="view" style="display: none">
<header class="view-header">
<h2 id="form-title">📦 Add Sync Provider</h2>
</header>

<form id="github-sync-form" class="sync-form">
<div class="form-group">
<label for="sync-name">Configuration Name</label>
<input type="text" id="sync-name" name="name" placeholder="e.g., My Project Tokens" required />
</div>
<div class="form-group">
<label for="sync-token">GitHub Personal Access Token (PAT)</label>
<input type="password" id="sync-token" name="token" placeholder="ghp_..." required />
<p class="help-text">Requires 'repo' scope.</p>
</div>
<div class="form-row">
<div class="form-group">
<label for="sync-repository">Repository (owner/repo)</label>
<input type="text" id="sync-repository" name="repository" placeholder="acme/design-system" required />
</div>
<div class="form-group">
<label for="sync-branch">Branch</label>
<input type="text" id="sync-branch" name="branch" placeholder="main" required />
</div>
</div>
<div class="form-group">
<label for="sync-path">Storage Path (in repo)</label>
<input type="text" id="sync-path" name="storagePath" placeholder="tokens.json" required />
</div>

<div class="form-actions">
<button type="button" id="cancel-sync" class="secondary-btn">Cancel</button>
<button type="submit" class="primary-btn">Save Configuration</button>
</div>
</form>
</div>

<!-- Modals -->
<div id="diff-modal" class="modal-overlay" style="display: none">
<div class="modal-content large">
<div class="modal-header">
<h2 id="diff-title">Review Changes</h2>
<button id="close-diff-btn" class="close-btn">&times;</button>
</div>
<div class="modal-body">
<p id="diff-message" class="diff-intro"></p>
<div id="diff-results" class="diff-scroll-area"></div>
</div>
<div class="modal-footer">
<button id="cancel-diff-btn" class="secondary-btn">Cancel</button>
<button id="confirm-diff-btn" class="primary-btn">Confirm & Sync</button>
</div>
</div>
</div>

<div id="commit-modal" class="modal-overlay" style="display: none">
<div class="modal-content">
<div class="modal-header">
<h2>Commit Message</h2>
<button id="close-commit-btn" class="close-btn">&times;</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="commit-message-input">What changed?</label>
<textarea id="commit-message-input" rows="3" placeholder="Updated colors from Penpot..."></textarea>
</div>
</div>
<div class="modal-footer">
<button id="cancel-commit-btn" class="secondary-btn">Cancel</button>
<button id="confirm-commit-btn" class="primary-btn">Push to GitHub</button>
</div>
</div>
</div>

<footer id="status" class="status"></footer>

<script type="module" src="/src/ui/index.js"></script>
</body>
</html>
Loading