Self-hosted service
author-more/penpot-desktop avatar
author-more/penpot-desktop

Penpot Desktop: a windowed shell around the Penpot web app

A desktop application for Penpot, an open-source design tool.

1,197 stars71 forksJavaScriptAGPL-3.0

At a glance

What is it?
Penpot Desktop is an unofficial Electron shell for the open source design tool Penpot, adding tabs, remembered open tabs, a dark and light theme setup, a local Docker instance creator and batch export. It suits a designer who wants the web tool to behave like an installed application, and it is a third party wrapper with its own licence obligations.
Who is it for?
Adopt Penpot Desktop if you work in Penpot all day and want the browser's tab discipline, remembered sessions and a proper application window without giving up the hosted or self hosted instance. Do not adopt it as a Penpot replacement, because it loads the Penpot web application rather than reimplementing it, so every feature still depends on the server you connect to, and an unofficial wrapper can lag behind the upstream interface.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A shell, not a reimplementation

Penpot Desktop is an unofficial desktop application for Penpot, the open source design tool, and the README is explicit about what that means. It loads the Penpot web application the way a browser does.

That single sentence defines the whole project, and it is worth being clear about it before anything else. There is no forked design engine here, no separate rendering pipeline, and no independent implementation of the Penpot editor. What you get is the Penpot web application running inside an Electron window, with the shell around it reworked.

The value proposition is therefore entirely in the shell. The feature list is a list of shell behaviours: a system-level application experience such as a dedicated window, a versatile dark-light mode setup, a tab interface for navigation between projects, open tabs that are remembered, the ability to connect to different instances such as the officially hosted one or a local one for offline work, a local instance creator based on the official Docker setup, batch export of projects, and auto-reload in the view mode.

Read that list as the answer to a specific irritation. Penpot in a browser tab is Penpot in a browser tab, and every time you switch to check documentation or your issue tracker you lose your place. The tab interface and the remembered tabs are the core of the product, and everything else is a convenience on top.

The project is licensed AGPL-3.0-or-later, which is the licence of the manifest, and it is by Author More. The last push to the main branch was on 2026-10-14, and the release history shows v1.0.0 on 2026-09-30, v0.25.0 on 2026-09-10 and v0.24.0 on 2026-08-27.

The offline story runs through Docker

The offline capability is the part of the project with the most moving parts, and the README describes it in one sentence. The built-in local instance creator can set up and run a local Penpot instance via Docker, following the official self-hosting guide.

That is a deliberate reuse rather than a reimplementation. Rather than maintaining a second way to run Penpot, the creator leans on the official Docker setup, which means the instance it gives you behaves like a self hosted deployment rather than something with a second set of rules. The trade-off is that the offline path inherits the requirements of the Docker setup, including Docker itself being present and working on the machine.

The connection model is the other half. The README lists the ability to connect to different instances, with the officially hosted one and a local one for offline work named as the examples, and the application reloads in the view mode. The self-hosting wiki page is linked from the quick links alongside the installation instructions and the offline-use guide, and the knowledge base is the project's documentation home.

Batch export of projects is the other feature that is more than a shell convenience, because exporting a set of projects by hand through the web interface means repeating the same steps per project. A batch action is the kind of thing a desktop wrapper can add and a web app cannot, at least not without an API for it.

Electron, tabs, and a set of small libraries

The dependency set is short and each entry explains a feature.

The main field points at src/process/index.js, which is the Electron main process entry, and the package type is module, so the whole application is ESM. The note in the README about Penpot Desktop using ES Modules points at the Electron guide on ES Modules in Electron, and that is the first thing to read if you are coming to the code.

The runtime dependencies are five. electron-tabs is the tab implementation, which is the feature the project is really about. electron-updater handles updates. @shoelace-style/shoelace is a web component library, which is what the shell uses for its own interface elements, since the Penpot application itself is loaded from the server. jszip handles the batch export, since project exports are archives. zod at 4.6.5 or newer validates configuration, which is the right choice for something that reads a local instance definition. And the trustedDependencies list names electron alone, which tells you the build is careful about which install scripts it allows to run.

The development dependencies follow a conventional Electron project. electron is at 44.5.0 or newer, electron-builder at 26.16.1 handles packaging, @playwright/test at 1.63.0 or newer drives the end to end tests, and there is a full linting and formatting stack: eslint 10 with the typescript-eslint plugin, prettier at 3.9.8, typescript at 6.0.3, and lint-staged with a.lintstagedrc.json for staged changes.

TypeScript appears as a development dependency and there is a tsconfig.json, with a compile:check script running tsc --noEmit, so the project is JavaScript at runtime with types checked statically.

Building it locally, and the scripts behind the workflow

The development instructions in the README are short and complete, which is a good sign for a project that has been through a few contributors.

The requirements are a supported operating system, with Windows, macOS and Linux named, plus Node.js, and Git marked optional. The README points at the prerequisites in the Electron documentation for the detailed list. You clone the repository or download the source, change into the project directory, and then:

code
npm ci

The note says other package managers such as Yarn or pnpm should work as well. Two optional steps follow, one that prepares the development environment and one that starts the application in development mode, opening a new window with the application running.

The build command is:

code
npm run build

By default it builds for the current operating system and architecture, and flags can be passed to build for other platforms, with the Electron Builder documentation linked for the details. There is also a separate build:arm script that targets arm64 explicitly, which matters for the Apple Silicon and Windows on ARM machines that are now a normal part of a designer's setup.

The quality scripts are worth noticing. The check script runs format:check, then lint, then tsc in sequence, so a single command covers formatting, linting and type checking. The test script is playwright test, with a playwright.config.ts at the repository root. Formatting has both a check mode and a write mode. There is a commitlint.config.js and a setup script that installs git hooks through a bin/setupGitHooks.sh script, so the commit message convention and the pre-commit checks are wired into the workflow rather than left to discipline.

Unofficial status, and what the AGPL means for the shell

Two things deserve attention before anyone builds on this.

The first is the unofficial status, which the README states in its opening line. Penpot Desktop is not part of the Penpot project. It is a separate application by Author More that loads Penpot. That distinction matters for two practical reasons. Interface drift is possible, because the web application is updated on the server side and the shell does not control it. And when something breaks, the fix is not in the Penpot repository.

The second is the licence, and it is the more consequential one. The project is AGPL-3.0-or-later, which is the strong copyleft licence. The AGPL's network clause is the part that catches people: it is the GPL condition plus a requirement that users interacting with a modified version over a network get the corresponding source. A desktop Electron application that loads a web application is an unusual shape for that clause to bite on, and this article does not give legal advice on how it applies here.

What is clear is the practical rule. If you are an organisation considering Penpot Desktop, the AGPL terms need reading by someone qualified, and the difference between running it unmodified for your own work and modifying or redistributing it is likely to matter. For personal use and for evaluation, the question does not usually arise.

For comparison, Penpot itself is the open source design tool this shell wraps, and the README links the official site at penpot.app as the first quick link.

Editorial conclusion

Adopt Penpot Desktop if you work in Penpot all day and want the browser's tab discipline, remembered sessions and a proper application window without giving up the hosted or self hosted instance. Do not adopt it as a Penpot replacement, because it loads the Penpot web application rather than reimplementing it, so every feature still depends on the server you connect to, and an unofficial wrapper can lag behind the upstream interface. Before you rely on it, check the AGPL-3.0-or-later terms for your organisation, and if you plan to work offline, verify that Docker is available on the machine, because the local instance creator is built on the official Docker setup.

Frequently asked questions

What does Penpot Desktop add to the Penpot web app?

It loads the Penpot web application inside an Electron window and adds a dedicated application window, a dark and light mode setup, a tab interface with remembered open tabs, the ability to connect to different instances, a local instance creator based on the official Docker setup, batch export of projects, and auto-reload in the view mode.

Can Penpot Desktop be used offline?

Yes. The built-in local instance creator can set up and run a local Penpot instance via Docker, following the official self-hosting guide, and the offline-use guide is in the project wiki. The README describes the local instance as one of the instances you can connect to alongside the officially hosted one.

How do I build Penpot Desktop from source?

You need a supported operating system with Windows, macOS or Linux, plus Node.js, and optionally Git. Run `npm ci` to install packages, optionally `npm run setup` and `npm run dev`, then `npm run build`, which by default targets the current OS and architecture but accepts flags for other platforms via electron-builder.

What licence is Penpot Desktop under?

AGPL-3.0-or-later, as declared in the package manifest. The project is by Author More and is an unofficial application, not part of the Penpot project itself.

Official sources

  1. author-more/penpot-desktop on GitHub
  2. Issues
  3. License: AGPL-3.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/author-more-penpot-desktop.svg)](https://hysenlabs.com/projects/author-more-penpot-desktop)

Was this useful?