Thanks to visit codestin.com
Credit goes to lib.rs

10 releases

Uses new Rust 2024

0.5.7 Apr 21, 2026
0.5.6 Apr 10, 2026
0.5.2 Mar 31, 2026
0.4.1 Mar 20, 2026
0.3.3 Mar 17, 2026

#1497 in GUI

MIT OR Apache-2.0 OR 0BSD

2.5MB
25K SLoC

native-theme-gpui

gpui + gpui-component connector for native-theme.

What it does

Turns a native_theme::ResolvedTheme into a fully configured gpui_component::theme::Theme — colors (108 fields), fonts, geometry, shadows, and icon mappings all wired up for every gpui-component widget.

How it fits

Depend on this crate — it pulls native-theme in transitively. The workspace-level README at the repo root has a diagram showing where each crate sits.

Quick start

Add both crates to your Cargo.toml:

[dependencies]
native-theme = "0.5"
native-theme-gpui = "0.5"

Load a bundled preset:

use native_theme_gpui::from_preset;

let (theme, resolved) = from_preset("dracula", true)?;
// `theme` is the gpui-component Theme; `resolved` has the raw native-theme data
//                                     ^ is_dark

Or read the OS theme at runtime:

use native_theme_gpui::from_system;

let (theme, resolved, is_dark) = from_system()?;

Core concepts

  • from_preset(name, is_dark) — load a bundled preset. is_dark is explicit because some presets (solarized, gruvbox) have ambiguous lightness.
  • from_system() — read the OS theme. Returns (theme, resolved, is_dark) so the third value tells you which variant the OS is currently using.
  • to_theme(&resolved, "App Name", is_dark, compact) — the underlying mapping function if you already have a ResolvedTheme from somewhere else.

Common recipes

Apply user overrides to the OS theme

use native_theme::{SystemTheme, theme::Theme};
use native_theme_gpui::to_theme;

let sys = SystemTheme::from_system()?;
let overlay = Theme::from_toml(r##"[light.defaults]
accent_color = "#ff6600"
"##)?;
let customised = sys.with_overlay(&overlay)?;
let active = customised.pick(customised.mode);
let theme = to_theme(active, "My App", customised.mode.is_dark(), false);

Custom icons

For app-specific icons generated via native-theme-build:

use native_theme_gpui::icons::custom_icon_to_image_source;
use native_theme::theme::IconSet;

let handle = custom_icon_to_image_source(&AppIcon::PlayPause, IconSet::Material, None, None);

Animated spinners

use native_theme::theme::AnimatedIcon;
use native_theme::icons::MaterialLoader;
use native_theme::detect::prefers_reduced_motion;
use native_theme_gpui::icons::{animated_frames_to_image_sources, with_spin_animation, to_image_source};

if let Some(anim) = MaterialLoader::load_indicator() {
    if prefers_reduced_motion() {
        let static_icon = to_image_source(anim.first_frame(), None, None);
    } else {
        match &anim {
            AnimatedIcon::Frames(_) => {
                // Cache this — do not call on every frame tick.
                let sources = animated_frames_to_image_sources(&anim, None, None);
            }
            AnimatedIcon::Transform(_) => {
                let spinner = gpui::svg().path("spinner.svg");
                let element = with_spin_animation(spinner, "loading", 1000);
            }
            _ => {}
        }
    }
}

What gets mapped

  • All 108 ThemeColor fields. ~30 direct mappings from the 24 semantic color roles; the other ~78 (hover/active states, chart colors, tab bar, sidebar, scrollbar, etc.) are derived via shade generation and alpha blending.
  • Fonts and geometryfamily, size, radius, shadow — into ThemeConfig. Font sizes pass through in logical pixels.
  • 30 of 42 IconRole variants mapped to gpui-component's IconName enum (actions, navigation, status indicators).

Reverse-mapping helpers (gpui-component → native-theme asset) live in the icons module: lucide_name_for_gpui_icon, material_name_for_gpui_icon, freedesktop_name_for_gpui_icon, plus to_image_source for converting loaded IconData to gpui::ImageSource.

Showcase

cargo run -p native-theme-gpui --example showcase-gpui

Displays every gpui-component widget (buttons, inputs, tables, charts, overlays, etc.) themed with native-theme presets, with live theme switching and a color map inspector.

Linux

KDE Breeze Light

KDE Breeze Dark

Material Light

Material Dark

Catppuccin Mocha Light

Catppuccin Mocha Dark

macOS

macOS Sonoma Light

macOS Sonoma Dark

Windows

Windows 11 Light

Windows 11 Dark

License

Licensed under any of

at your option.

Dependencies

~58–115MB
~2M SLoC