Skip to content

Repository files navigation

HeroGPUI

HeroGPUI is a UI library for Rust desktop applications. It brings the HeroUI design system to Rust, built on GPUI, the GPU-accelerated framework behind the Zed editor. It runs on Windows, macOS and Linux from one codebase.

It implements every component HeroUI documents — 71 components, shown in the gallery and on the website as 66 pages because a few pages cover a component together with its group or slot siblings.

use herogpui::*;

impl Render for MyApp {
    fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
        app_focus_root(div()
            .size_full()
            .bg(cx.colors().background)
            .child(
                Button::new("save")
                    .label("Save changes")
                    .variant(Variant::Primary)
                    .on_press(cx.listener(|this, _, _, cx| this.save(cx))),
            ), window, cx)
    }
}

Installation

Prerequisites: Rust 1.98 and the platform tooling GPUI needs (Xcode on macOS; Wayland/X11 dev packages on Linux; nothing extra on Windows).

herogpui is not on crates.io yet. Depend on the git repository:

[dependencies]
herogpui = { git = "https://github.com/Porabuild/HeroGPUI" }

That is the whole list. A path dependency works the same way against a local checkout. herogpui is a facade: it depends on the matching gpui-pre and gpui-pre-platform crates and re-exports them, so use herogpui::*; is GPUI and herogpui::application() opens the platform. Do not add gpui or gpui_platform to your own Cargo.toml — a second copy of GPUI is how versions drift apart. (Zed does not publish gpui under that name, which is why GPUI arrives as gpui-pre, zed-industries' own prerelease publish of the same sources. The unrelated crates.io gpui 0.2.2 crate is a different library.)

Each layer is also reachable by name, and each is a Cargo feature:

Path Crate Feature
herogpui::* gpui always
herogpui::platform, herogpui::application gpui_platform always
herogpui::core herogpui-core core (via theme)
herogpui::theme herogpui-theme theme (via components)
herogpui::components, herogpui::* herogpui-components components (default)
herogpui::web gpui_platform always, cfg(wasm) only

Two more features only forward to GPUI: test-support (gpui/test-support + gpui_platform/test-support, for your own #[gpui::test]) and profiler (gpui/profiler). serde forwards herogpui-theme/serde and is off by default: it is the sparse ThemeDocument JSON applied through ThemeBuilder, not a dump of a resolved Theme.

Then, inside application().run(..):

  1. Register the embedded icons with herogpui::application().with_assets(HeroGpuiAssets), or HeroGpuiAssets::with_fallback(MyAppAssets) when the app has assets of its own.
  2. Initialize the enabled layers with herogpui::init(cx) before opening a window. That is ThemeProvider::init(cx); call ThemeProvider::init_with(theme, cx) instead to start from a custom theme.
  3. Wrap the root element with app_focus_root(root, window, cx) so Tab and focus-visible behavior work across components.
  4. Set the background, foreground and font family on the root view from tokens.

The whole program, with herogpui as its only dependency:

use herogpui::*;

actions!(demo, [Quit]);

struct Hello;

impl Render for Hello {
    fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
        app_focus_root(
            div()
                .size_full()
                .bg(cx.colors().background)
                .text_color(cx.colors().foreground)
                .font_family("Helvetica")
                .child(Button::new("save").label("Save changes")),
            window,
            cx,
        )
    }
}

fn main() {
    application().with_assets(HeroGpuiAssets).run(|cx: &mut App| {
        herogpui::init(cx);
        let bounds = Bounds::centered(None, size(px(1280.), px(820.)), cx);
        cx.open_window(
            WindowOptions {
                window_bounds: Some(WindowBounds::Windowed(bounds)),
                ..Default::default()
            },
            |_, cx| cx.new(|_| Hello),
        )
        .expect("failed to open window");
    });
}

That program is a doctest in crates/herogpui/src/lib.rs, so cargo test --doc -p herogpui compiles it rather than this file asserting that it would. actions! is HeroGPUI's own copy of GPUI's macro: the upstream one expands its derive as the absolute path gpui::Action, which does not resolve when GPUI is reached only through a facade. Eight names — ColorSpace, FontWeight, Menu, MenuItem, Orientation, Size, Surface and TextAlign — exist in both GPUI and HeroUI v3; at herogpui's root the HeroUI spelling wins, and GPUI's keep the gpui:: path (gpui::Size).

Gallery

A desktop gallery ships with the library and documents every component:

cargo run -p herogpui-gallery   # open the component gallery
cargo install --path gallery --locked  # install the gallery CLI from this checkout

HEROGPUI_PAGE and HEROGPUI_THEME select the page and appearance; HEROGPUI_WINDOW_SIZE sets the window size.

Documentation

  • Website: https://porabuild.com/herogpui — every component page embeds HeroGPUI compiled to WebAssembly, running live next to its Rust code.
  • llms.txt at the repository root: the full component API reference for agents. It is served verbatim at https://porabuild.com/herogpui/llms.txt.
  • AGENTS.md and docs/agents/: the contributor and agent guides.

Verification

Audit tooling under .shots/ checks the implementation against the upstream design system. See docs/agents/parity.md for what each audit reads and what it proves. The lint gate is .shots/lint.ps1.

License

Apache-2.0. This library derives component behavior, design tokens, styles, and documentation structure from HeroUI, Copyright 2025 NextUI Inc., also Apache-2.0. See LICENSE and NOTICE.

About

Native Rust/GPUI port of HeroUI v3

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages