# Druid: the unmaintained Rust UI toolkit and what it still gives you

> Druid is a data-first Rust-native UI toolkit that Linebender has discontinued in favour of Xilem. The 0.8.3 release still builds and its architecture is worth understanding, but the README tells new projects to look elsewhere.

**linebender/druid** — A data-first Rust-native UI design toolkit. 

- Repository: https://github.com/linebender/druid
- Website: https://linebender.org/druid/
- Stars: 9,703 · Forks: 565
- Language: Rust
- License: Apache-2.0
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/linebender-druid

## What Druid was trying to be, and who it was for

Druid is a desktop UI toolkit written in Rust, built around the idea that application state is a single data value that widgets read from and write to. The README frames the goal as a polished user experience: performance, a widget library rich enough to cover common interactions, and behaviour that fits the native platform. It targets developers writing desktop-grade applications in Rust who want layout, input handling and platform abstraction from one dependency rather than assembling those pieces themselves.

The README is blunt about where the project stands. It carries the status UNMAINTAINED and states that the Druid project has been discontinued. Development moved to Xilem, which the README describes as heavily inheriting from Druid while making fundamental changes for a wider variety of applications and better performance. Contributions are closed. That single paragraph is the most important thing on the page, and it should shape every decision about whether to read further.

## The data-first model: one value, many widgets

The architecture rests on a generic application state type. In the counter example the state is a u32, and the launcher takes that value by value: AppLauncher::with_window(main_window).launch(data). Widgets are parameterised by the same type, so a Label is a Widget<u32> and a Button is a Widget<u32>, and the tree is composed from children that all agree on that type.

Events do not mutate the tree. The button in the example carries an on_click closure whose second argument is the data, and the closure does the mutation: *data += 1. The label does not hold a copy of the number. It holds a LocalizedString whose argument is computed from the current data through a closure, so the displayed text is derived rather than stored. That is what data-first means in practice: one source of truth, widgets that project from it, and callbacks that write back to it.

Underneath, druid-shell owns the platform runloop. It starts a native loop, listens for events, converts them into a platform-agnostic representation, and calls a handler. Drawing and text layout go through Piet, which has separate backends: piet-coregraphics on macOS, piet-cairo on Linux, OpenBSD and FreeBSD, piet-direct2d on Windows, and piet-web for the web target. Druid re-exports the parts of druid-shell, piet and kurbo that an application needs, so the common case is a single dependency.

## Installing Druid and building the counter

Druid is published on crates.io and the README gives the dependency line directly. Add it to Cargo.toml at the last published version:

```toml
druid = "0.8.3"
```

On Linux there is a system prerequisite. The README states that Druid requires gtk+3 and points at the GTK installation page; on Ubuntu-based distributions it gives the apt command:

```bash
sudo apt-get install libgtk-3-dev
```

On OpenBSD the same requirement is met from packages:

```sh
pkg_add gtk+3
```

The README also notes an X11 backend on OpenBSD, enabled with --features=x11, and warns that it is missing quite a few features.

The smallest real program is the counter from the README. It creates a window description, launches with a u32 as the application data, and builds a column containing a label and a button:

```rust
use druid::widget::{Button, Flex, Label};
use druid::{AppLauncher, LocalizedString, PlatformError, Widget, WidgetExt, WindowDesc};

fn main() -> Result<(), PlatformError> {
    let main_window = WindowDesc::new(ui_builder());
    let data = 0_u32;
    AppLauncher::with_window(main_window)
        .log_to_console()
        .launch(data)
}
```

Running this opens a window with the label and an increment button; clicking the button adds one to the u32 and the label text recomputes from the new value. The README points at the examples folder for a fuller demonstration of the existing widgets, and at druid_widget_nursery for widgets outside the core crate. The repository layout matches that promise: a druid workspace member, a druid-shell member, a druid-derive member for macros, and a docs directory holding the incomplete Druid book.

## Where Druid falls short, by its own account

The README lists accessibility and 3D support as features Druid does not have, and tells anyone who insists on using it to make sure their application does not require them. That is a hard boundary, not a roadmap item, because the project no longer accepts contributions.

The same paragraph concedes the scope is partial. Druid is described as reasonably usable for some subset of applications, with a link to issue 1360 for the details of that subset. A toolkit that is usable for a subset of applications is a different proposition from one that is usable for applications generally, and the difference matters most when you discover it late.

The X11 backend on OpenBSD is a second example of the same pattern. It exists and can be switched on, but the README says it is missing quite a few features and links to the issue list filtered by the shell/x11 and missing labels. If your target is a platform where the only working backend is the incomplete one, the toolkit is the wrong tool, and no amount of reading the widget code will change that. Finally, the release history shows the shape of the project: v0.8.3 landed on 2023-02-28, and the README says there will be no new features or bug fixes. The repository received a push on 2026-04-23, but that is not a release and the README's own statement about the project's status is the relevant fact.

## Xilem is the successor, and the difference is architectural

The README names Xilem as Druid's successor and says new development effort moved there. It describes Xilem as heavily inheriting from Druid while introducing fundamental changes that allow a wider variety of applications with better performance. That is more than a rename: the phrase fundamental changes is doing real work, and it implies that code written against Druid's data-first model will not carry across unchanged.

The README's non-goals section names other projects for cases Druid deliberately did not cover, and the distinctions are concrete. Relm and Slint are named for using or mimicking platform-native widgets. Conrod is named for embedding into custom render pipelines. Iced and Relm are named for adhering to a specific architectural style such as Elm. Iced and Moxie are named for rendering to HTML when targeting the web. If what you actually want is a native-looking widget set, or an Elm-style update loop, Druid was never designed to give it to you, and the README says so before you install anything.

Choosing between Druid and Xilem today is not a close call for new work. The README recommends against Druid for brand new applications. The realistic choice is between Xilem and one of the alternatives above, with Druid relevant mainly to people with existing code.

## Licence, upgrade cost, and what a Druid dependency commits you to

Druid is licensed under Apache-2.0. The repository carries a LICENSE file at the top level, and the crates.io badge in the README links to it. Apache-2.0 is a permissive licence with an explicit patent grant, and it is compatible with the usual practice of shipping a compiled binary. Nothing here is legal advice, and if you redistribute a modified Druid you should read the licence text itself rather than a summary.

The upgrade cost is the part people underestimate. Druid re-exports parts of druid-shell, piet and kurbo, and the workspace holds all three as separate members alongside druid-derive and a docs directory of book examples. A dependency on druid therefore pulls in a graphics abstraction with per-platform backends and a shell layer that owns the runloop. When those upstream crates move, a pinned Druid does not follow, and the README states there will be no bug fixes. If a platform update breaks the build, the fix is yours to carry, and the workspace layout is the map of where to look.

The version to pin is 0.8.3, published on 2023-02-28. The changelog in the repository documents what changed in each release, and it is the only record of behaviour changes you will get.

## Conclusion

Druid is for reading, porting, or maintaining an existing 0.8.3 application, not for starting one: the README says there will be no new features or bug fixes and points new work at Xilem. If you do build on it, verify first that your application needs neither accessibility nor 3D support, since the README names both as gaps. Clone the repository and run the examples in druid/examples before committing to anything.

## FAQ

### Is Druid still maintained?

No. The README marks the project UNMAINTAINED and states it has been discontinued, with no new features or bug fixes coming, and contributions are closed.

### How do I install Druid in a Rust project?

Add druid = "0.8.3" to Cargo.toml. On Linux you also need gtk+3, which the README installs on Ubuntu-based distributions with sudo apt-get install libgtk-3-dev, and on OpenBSD with pkg_add gtk+3.

### What should I use instead of Druid for a new Rust GUI application?

The README points to Xilem as Druid's successor, describing it as heavily inheriting from Druid but with fundamental changes for a wider variety of applications and better performance. It also names Relm and Slint for platform-native widgets and Iced for an Elm-style architecture.

### Does Druid support accessibility or 3D rendering?

The README lists both as features Druid does not have, and advises anyone who insists on using Druid to make sure their application does not require them.

### Which graphics backend does Druid use on each platform?

Drawing and text layout go through Piet: piet-coregraphics on macOS, piet-cairo on Linux, OpenBSD and FreeBSD, piet-direct2d on Windows, and piet-web for the web target.

### Can I use the X11 backend on OpenBSD?

It exists and is enabled with --features=x11, but the README says it is currently missing quite a few features and links to the open issues labelled shell/x11 and missing.

## Sources

- [License: Apache-2.0](https://github.com/linebender/druid/blob/master/LICENSE)
- [linebender/druid on GitHub](https://github.com/linebender/druid)
- [Project website](https://linebender.org/druid/)
- [README](https://github.com/linebender/druid/blob/master/README.md)
- [Releases](https://github.com/linebender/druid/releases)

---

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