# Penrose: diagrams from plain text notation

> Penrose is an MIT-licensed TypeScript platform from Carnegie Mellon that turns Domain, Substance and Style programs into diagrams. It suits people who want visual output defined by constraints rather than drawn by hand, and it asks for a text editor and a tolerance for solver behaviour.

**penrose/penrose** — Create beautiful diagrams just by typing notation in plain text.

- Repository: https://github.com/penrose/penrose
- Website: https://penrose.cs.cmu.edu
- Stars: 7,985 · Forks: 365
- Language: TypeScript
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/penrose-penrose

## What Penrose solves, and who it is for

Most diagram tools make you place every shape. Penrose inverts that. You describe the objects and their relationships in text, and the system computes a layout that satisfies the relations you declared. The README frames the goal as making it easy for non-experts to create and explore high-quality diagrams, and as democratizing the process of creating visual intuition. The audience implied by that framing is people who understand a technical concept but do not want to become illustrators: a lecturer preparing set theory figures, a researcher who needs the same diagram regenerated with different data, a student who wants to see what a definition implies.

The problem it targets is repetition. If you draw a Venn diagram by hand and then add one more set, you redraw it. In Penrose, you add a line to the Substance program and the layout is recomputed. That is the whole value proposition, and it is a narrow one. Penrose is not a general vector editor, and it does not try to be.

## Domain, Substance and Style: the three-program model

Every Penrose diagram is built from three separate programs, and the README's set theory example shows all three.

A Domain program declares the vocabulary. In the example it defines a type Set and three predicates: Disjoint, Intersecting and Subset. It says nothing about appearance.

A Substance program declares the concrete objects and facts. The example lists Set A through G, then asserts Subset(B, A), Subset(C, A), Disjoint(E, D) and so on, and ends with AutoLabel All. It says nothing about appearance either.

A Style program maps the vocabulary onto shapes and layout relations. The example declares a canvas of width 800 and height 700, gives every Set a Circle icon and an Equation label, and then writes conditional blocks: for Subset(x, y) it requires the label of y to stay clear of the icon of x and the icon of y to contain the icon of x; for Disjoint(x, y) it requires the two icons to be disjoint; for Intersecting(x, y) it requires them to overlap. Keywords like ensure, encourage and layer carry the layout intent.

That separation is the architecture. The Domain and Substance layers are declarative and reusable; the Style layer is where the drawing decisions live. A different Style program over the same Substance produces a different picture without touching the data. The README also notes the example output corresponds to a specific variation, MonsoonCaterpillar95943, which tells you the layout is not a single deterministic answer. The solver searches, and the variation selects which solution you get.

## Trying Penrose in the browser before installing anything

The README points to a browser version at penrose.cs.cmu.edu/try/index.html that requires no installation, and to a step-by-step tutorial and a reference manual on the same site. If you are evaluating the notation, start there. The browser editor is the fastest way to see whether the three-program model matches how you think about your diagrams, and it avoids the Node toolchain entirely.

Installation is only worth doing when you want Penrose inside your own build, or when you need the packages programmatically. The README does not give install commands for the repository itself; it links to the documentation site for that. What the repository does show is the shape of the project: a yarn workspace with a packages/ directory, an nx build graph, and a root package.json that requires Node ^18.12.0 or >=20.9.0.

From the repository layout, the standard path for a workspace of this kind is to clone it and install dependencies with yarn, then use the nx targets defined in the root scripts.

```bash
yarn install
yarn build
```

The build script runs nx run-many with the build and bundle targets, so it compiles every package in the workspace rather than one. Expect that to take a while on a cold cache. For an editor session during development, the root package.json defines a start script that runs the editor package in watch mode.

```bash
yarn start
```

The README does not document what port that editor serves on, so check the terminal output rather than assuming a default. For the published library, the README's badge points at the npm package @penrose/core, which is the package you would depend on if you are embedding Penrose rather than running the editor.

## Where Penrose is the wrong tool

The three-program model is a real cost. To draw one diagram you write a Domain, a Substance and a Style file, and you have to keep the vocabulary consistent across all three. For a single figure that will never be regenerated, that is more work than dragging shapes in a vector editor, and the result will be less precisely controlled.

Layout is computed, not specified. The Style program states relations like contains and disjoint, and the solver finds an arrangement that satisfies them. When your constraints conflict or are too loose, you do not get an error pointing at a line you can fix; you get a layout you did not want, or you change the variation and try again. The README's own example output is tied to a named variation, which is a hint that reproducing an exact picture means recording that variation rather than expecting the same result every run.

There is also a hard boundary around what a diagram can express. Penrose is built for notation-driven figures: sets, graphs, geometry, relations. If your output is a hand-tuned illustration, a map with cartographic detail, or anything where the visual hierarchy is the point rather than the structure, the constraint solver is working against you. And if your diagram is generated once and shipped as a static asset, a plotting library will get you there with less machinery.

## How Penrose differs from drawing and plotting libraries

The obvious alternative is a declarative drawing library such as D3 or a plotting library such as matplotlib. The difference is where the layout decision lives.

With D3, you compute positions in code and emit SVG. You own the geometry. If you want labels not to overlap, you write the collision logic or pull in a force simulation and tune it. The output is exactly what your code says, which is an advantage when you need precision and a burden when the diagram has many interacting parts.

Penrose moves that responsibility into the Style program and the solver. You declare that one label must stay clear of one icon and let the system find coordinates. That is a better fit when the diagram's structure is what matters and the exact coordinates are not, and it is a worse fit when you need to reproduce a specific published figure down to the pixel.

The second alternative is a GUI diagram editor. Those give you direct manipulation and immediate feedback, and they give you nothing when the data changes. Penrose's bet is that a text description plus a solver beats both for diagrams that need to be regenerated, versioned and diffed alongside code.

## Maintenance, releases and licence cost

The repository is not archived, and the last push was on 2026-08-31. The release history shows v3.3.1 on 2026-08-30, v3.3.0 on 2025-09-28 and v3.2.0 on 2023-08-08. Read those dates together and the cadence is uneven: roughly two years between 3.2.0 and 3.3.0, then a patch about eleven months later. A project with that rhythm is maintained, but you should not plan around frequent breaking changes or a fast response to issues.

The upgrade cost is concentrated in the Style language and the package API. The jump from 3.2.0 to 3.3.0 is a minor version, but Penrose diagrams are source files in your repository, so a change in how ensure or encourage behaves can alter every figure you have committed. Treat your .style, .domain and .substance files as code that needs review when you bump the dependency, not as assets.

The repository is licensed under the MIT License. That is permissive: it allows commercial use, modification and redistribution provided the copyright notice and permission notice are included. The README states the licence and links to the LICENSE file; it does not discuss contributor licensing or trademark terms for the Penrose name. If you are embedding the packages in a product, read the LICENSE file in the repository rather than relying on the badge, and take your own legal advice on attribution in your distribution.

## Conclusion

Adopt Penrose if your diagrams are structural and repeatable, and you are willing to write three small programs instead of opening a drawing tool. Do not adopt it if you need pixel-level control over a one-off figure, or if a diagramming library you already ship can express the same output. Before committing, verify two things: that the current release installs cleanly on a supported Node version, and that the Style language can express the layout relations your diagrams actually need, since the solver enforces constraints rather than letting you place shapes by hand.

## FAQ

### What is Penrose?

Penrose is a platform for creating diagrams by typing notation in plain text. It is developed at Carnegie Mellon and licensed under the MIT License, with the source in a TypeScript monorepo.

### What is Penrose known for?

The README describes it as a platform that lets people create beautiful diagrams just by typing notation in plain text, with the stated goal of making it easy for non-experts to create and explore high-quality diagrams.

### How do I use Penrose?

You write three programs: a Domain that declares types and predicates, a Substance that declares concrete objects and facts, and a Style that maps them onto shapes and layout relations. The README points to a browser version that needs no installation and to tutorials and reference documentation on the project site.

## Sources

- [License: MIT](https://github.com/penrose/penrose/blob/main/LICENSE)
- [penrose/penrose on GitHub](https://github.com/penrose/penrose)
- [Project website](https://penrose.cs.cmu.edu)
- [README](https://github.com/penrose/penrose/blob/main/README.md)
- [Releases](https://github.com/penrose/penrose/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/penrose-penrose
