# Piet 2D Graphics API for Rust: Backends, Setup, and Limits

> Piet gives Rust applications a common 2D drawing API backed by Cairo, Core Graphics, Direct2D, SVG, or WebAssembly. It is aimed at teams that want portable drawing code without embedding a complete renderer, but its maintenance mode and platform constraints require careful adoption.

**linebender/piet** — An abstraction for 2D graphics.

- Repository: https://github.com/linebender/piet
- Stars: 1,374 · Forks: 99
- Language: Rust
- License: Apache-2.0
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/linebender-piet

## Why Piet Exists in a Rust Graphics Stack

Piet addresses a specific portability problem: Rust drawing code often has to choose between platform graphics APIs, a large rendering engine, or separate implementations for different operating systems. Piet places a small 2D API in the `piet` crate and delegates drawing to platform-specific backends. The same application-level drawing code can therefore call a common interface while the selected backend uses the host graphics system.

The project is intended for Rust developers building cross-platform interfaces, custom controls, diagrams, or other software that needs paths, filled areas, strokes, text, images, and related 2D operations. The README says Piet forms the basis of Druid, a cross-platform GUI toolkit, which is a concrete example of the kind of shared drawing foundation it supports. It is not presented as a complete retained-mode UI framework, scene graph, animation engine, or windowing package.

Piet also separates 2D geometry from rendering. The companion `kurbo` project provides Bézier paths and geometry, allowing callers to represent shapes independently of the backend that eventually draws them. This division can keep geometry-heavy code separate from platform code, although adopting both projects means managing their APIs and versions.

## The Piet API and Its Backend Boundary

Based on the repository layout, the central `piet` crate defines the graphics API, while separate crates implement it through Cairo, Apple Core Graphics, Microsoft Direct2D, SVG, or the web platform. `piet-common` sits above those implementations and reexports the most appropriate one for the current target. That makes backend selection part of dependency management rather than a requirement to copy every drawing routine.

The native backend split is explicit. `piet-cairo` depends on the Cairo library and is associated with the Cairo graphics stack. `piet-coregraphics` works on macOS only. `piet-direct2d` works on Windows only. The README does not claim that these implementations expose identical capabilities merely because they implement the same core API. Significant new functionality is expected to have a plan for `coregraphics`, `direct2d`, and `cairo`, with actual support in at least two of them. This is a concrete indication that cross-platform parity requires deliberate implementation work.

The `piet-svg` and `piet-web` crates provide other targets. The repository includes a basic example under `piet-web/examples/basic`, while `piet-svg` is listed as its own workspace member. The README does not document a complete feature matrix, text shaping rules, image formats, blend modes, or backend-specific APIs, so an adoption decision cannot safely assume that SVG, web, and native targets behave identically.

## Preparing the Piet Workspace and Running a Native Example

The README does not provide a crate installation command or a complete application setup recipe. It directs contributors and users who want the repository examples to check out submodules first. Run this from the repository root before attempting to run the examples.

```bash
git submodule update --init
```

The workspace uses Rust edition 2024 and declares Rust 1.92 as its minimum supported version. Piet has been verified to compile with Rust 1.92 and later, and the README warns that a future version may raise that requirement even in a patch release.

For a first native example, select the backend that matches the operating system and documentation. From the `piet-cairo` directory, the documented command is:

```bash
cargo run --example test-picture 0
```

The README says this should produce `cairo-test-00-2.00.png`. That makes the first use concrete: the command runs an example, passes picture index `0`, and writes an image in the current backend directory. On macOS, use the same documented example argument from `piet-coregraphics`, where the expected output is `coregraphics-test-00-2.00.png`. On Windows, the corresponding `piet-direct2d` example should produce `d2d-test-00-2.00.png`. These are separate backend checks, not one command that is portable across all three platforms.

## Choosing piet-common, Cairo, Core Graphics, or Direct2D

Use `piet-common` when the application should let target selection choose the implementation. Its stated purpose is to reexport the most appropriate backend for the current target. This fits applications whose drawing code is shared and whose deployment target is known when the dependency graph is built.

A direct backend dependency is more appropriate when native system integration, output inspection, or platform-specific testing matters. The choice also affects installation requirements. The README explicitly states that `piet-cairo` depends on the Cairo library, so adopting that backend adds an external system dependency. `piet-coregraphics` is limited to macOS, while `piet-direct2d` is limited to Windows. The README does not state that `piet-common` eliminates all native prerequisites or removes the need to consider the selected backend.

For backend-specific development, use the example command in the relevant backend directory and confirm the documented output filename. This is more informative than only compiling the workspace because it exercises the selected implementation's `test-picture` example. The README does not provide CI commands for producing all native outputs on one machine, so cross-platform verification must account for operating-system availability.

## Piet's Stabilized Scope and Backend Parity Constraint

The most important adoption constraint appears in the contributing section: Piet is in maintenance mode. The original developers state that the API has largely stabilized and that no major API additions are planned. Bug fixes and performance improvements are welcome. That status is more consequential than the repository's non-archived status and should shape expectations for roadmap planning.

A significant feature is not accepted merely because it would improve one backend. The documented condition requires a plan covering `coregraphics`, `direct2d`, and `cairo`, plus implementation in at least two. This prevents casual divergence, but it also creates a real coordination cost for projects whose needs are specific to Windows, macOS, SVG, or the web. A required API that lacks portable semantics may need work in several implementations or remain unavailable.

The project does not present itself as a full renderer comparable to the Skia Graphics Library. Its interface was inspired by Skia and the C++ 2D graphics API proposal, with a lighter and more modular goal. Teams that need a bundled renderer, a large predefined effect catalog, or a complete application graphics stack may find Piet too small. Teams that mainly need a shared drawing surface through native operating-system APIs are the closer match.

## Rust Toolchain and Dependency Upgrade Costs

The current workspace version is `0.8.0`, matching the listed `v0.8.0` release. The workspace pins its related Piet crates to that exact version through path dependencies, which keeps the repository's internal packages aligned. Applications embedding Piet still need to account for Rust's dependency resolver when adding the crate to their own project, although the README does not document a preferred application-level dependency declaration.

The MSRV is unusually explicit: Rust 1.92 or later is required, and the repository uses edition 2024. Future releases may increase the minimum version without being classified as a breaking change. For automation, the version check must therefore include minor and patch upgrades rather than assuming compatibility can only change in a major release.

The README gives one dependency-downgrade command template for compilation problems caused by a dependency that has raised its Rust requirement:

```bash
cargo update -p package_name --precise 0.1.1
```

The placeholders must be replaced with the actual package and compatible version. This is a toolchain workaround rather than documented Piet policy. A lockfile-based application can reduce dependency movement, while a library must avoid forcing unsuitable requirements on downstream users. The repository includes `Cargo.lock`, but the README does not state that consumers should commit it in every project type.

The last push was on 2026-05-02. That date is relevant for judging repository activity, but the explicit maintenance-mode statement is the stronger signal about future feature work.

## Piet License Choices for Rust Projects

The workspace metadata declares `Apache-2.0 OR MIT`, and the README says users may select either Apache License, Version 2.0 or the MIT license. The repository contains separate `LICENSE-APACHE` and `LICENSE-MIT` files. This dual-license structure gives an adopter a choice between two stated license options rather than requiring one combined custom grant.

The README also includes the standard contribution notice: contributions submitted for inclusion are licensed as stated in the project's License section unless the contributor explicitly states otherwise. That is relevant to organizations reviewing inbound patches, while end users normally rely on the published dual-license terms.

This review does not interpret legal obligations. An organization should check the actual license files and its dependency graph for notices or incompatible terms. It should also account for native components such as Cairo when applicable, since choosing a license for Piet does not by itself settle the licensing of every external library linked into an application.

## Conclusion

Adopt Piet when portable Rust drawing code is more important than adding a new renderer. Do not adopt it when you need planned major API expansion or a fully uniform feature set across native backends. Check target-platform compatibility, the selected backend's dependencies, and your required Rust version first, because Piet is in maintenance mode and requires Rust 1.92 or later.

## FAQ

### How do I install the Piet examples from GitHub?

The README says to run `git submodule update --init` from the repository root before running the examples. It does not give a separate crate installation command.

### Which Rust version does Piet require?

Piet has been verified with Rust 1.92 and later. The README warns that a future release may increase the Rust requirement without treating it as a breaking change.

### Can I use Piet on macOS, Windows, and Linux through the same API?

Piet defines a shared 2D API and offers native backends including Cairo, Core Graphics for macOS, and Direct2D for Windows. `piet-common` selects an implementation for the current target, but the README does not publish a complete feature-parity matrix.

## Sources

- [Issues](https://github.com/linebender/piet/issues)
- [License: Apache-2.0](https://github.com/linebender/piet/blob/main/LICENSE)
- [linebender/piet on GitHub](https://github.com/linebender/piet)
- [README](https://github.com/linebender/piet/blob/main/README.md)
- [Releases](https://github.com/linebender/piet/releases)

---

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