gpuicn Guide

Chapter 2

Installation

Add a component to a GPUI app, one step at a time. Each step says what it writes and what you should see.

You need Rust 1.98 or newer and your platform's native build tools. On macOS that is Xcode's Metal toolchain. On Ubuntu, install GPUI's libraries first:

sudo apt-get install libfontconfig1-dev libxcb1-dev libxkbcommon-dev libxkbcommon-x11-dev libwayland-dev

1 Create the app

Create a crate and add the pinned dependencies to Cargo.toml:

cargo new my-app
cd my-app

[dependencies]
web-time = "1.1"
gpui_platform = { package = "gpui-pre-platform", version = "=0.3.11", features = ["font-kit"] }
gpui-icons = "=0.6.0"

gpui-kit = { version = "=0.9.0", default-features = false, features = ["component"] }

[dev-dependencies]
gpui-kit = { version = "=0.9.0", default-features = false, features = ["component", "test-support"] }

Import GPUI types through gpui_kit, never through a second gpui dependency, so your views and the components share one set of types.

2 Install the CLI

cargo install gpuicn-cli --version 0.9.5 --locked

Then, from the app root, write gpuicn.toml against the registry for the same release:

gpuicn --registry https://raw.githubusercontent.com/devaryakjha/gpuicn/v0.9.5/site/pages/r init

The file it writes:

version = 2
registry = "https://raw.githubusercontent.com/devaryakjha/gpuicn/v0.9.5/site/pages/r"
output = "src/ui"

[theme]
base_color = "neutral"
appearance = "system"

The registry URL pins component source to v0.9.5. Fixes made after that tag are not included until you change the URL.

3 Add a component

gpuicn add button

This writes src/ui/button.rs and src/ui/theme.rs, and creates or updates src/ui/mod.rs to declare them:

pub mod button;
pub mod theme;

Add mod ui; to src/main.rs. The files under src/ui are yours to edit.

4 Add the fonts

Download the pinned Geist files and their license into assets/fonts:

mkdir -p assets/fonts
for file in Geist-Regular.ttf Geist-Medium.ttf Geist-SemiBold.ttf GeistMono-Regular.ttf; do
  curl -fL "https://raw.githubusercontent.com/devaryakjha/gpuicn/v0.9.5/site/assets/fonts/$file" -o "assets/fonts/$file"
done
curl -fL "https://raw.githubusercontent.com/devaryakjha/gpuicn/v0.9.5/LICENSES/Geist-OFL-1.1" -o assets/fonts/OFL.txt

5 Open a window

Replace src/main.rs with the starter:

mod ui;

use gpui_kit::{Context, IntoElement, ParentElement as _, Render, Styled, Window, div, px};
use ui::{
    app::{AppConfig, run},
    app_theme,
    button::Button,
    theme::UiTheme,
};

fn main() {
    // Opens the window with the Lucide icons, the Geist fonts and the theme pair
    // from assets/theme.css; `gpuicn theme set` changes the base color, radius
    // and appearance.
    run(
        AppConfig::new("My App")
            .themes(app_theme::light(), app_theme::dark())
            .appearance(app_theme::APPEARANCE),
        |_, _| Hello { count: 0 },
    );
}

struct Hello {
    count: usize,
}

impl Render for Hello {
    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
        let theme = UiTheme::read(cx);
        div()
            .size_full()
            .flex()
            .items_center()
            .justify_center()
            .p(px(24.))
            .bg(theme.colors.background)
            .text_color(theme.colors.foreground)
            .font_family(theme.fonts.body.clone())
            .child(
                Button::new("hello.increment")
                    .aria_label(format!("Clicked {} times", self.count))
                    .on_click(cx.listener(|this, _, _, cx| {
                        this.count += 1;
                        cx.notify();
                    }))
                    .label(format!("Clicked {} times", self.count)),
            )
    }
}

cargo run

You should see a window with one button that counts its clicks. Switch the system appearance and the window changes with it. gpuicn theme set changes the base color, the radius, and the appearance.

Updating to a newer release

A new release can change installed source. To take the changes, commit your own edits first, so the diff after the update shows only what the release changed.

  1. Install the newer CLI with cargo install gpuicn-cli --version <new> --locked --force.
  2. Change the registry URL in gpuicn.toml to the same release tag.
  3. Preview, replace, then review:
gpuicn add button --dry-run --overwrite
gpuicn add button --overwrite
git diff -- src/ui

Reapply the edits from your earlier commits that you still need.