native-theme
What it does
Cross-platform theme data model with 24 semantic color roles, 25 per-widget
themes, and 16 bundled TOML presets. Reads OS themes from KDE Plasma, GNOME
(via xdg-desktop-portal), macOS, and Windows, and produces a fully populated
ResolvedTheme any GUI toolkit can consume.
How it fits
Most apps don't depend on this crate directly — they use a framework connector like
native-theme-gpui or
native-theme-iced, which pull native-theme in
transitively. Depend on native-theme directly only if you are writing a new connector.
Quick start
Add the dependency:
Read the live OS theme:
use SystemTheme;
let sys = from_system?;
let active = sys.pick; // &ResolvedTheme
let accent = active.defaults.accent_color; // Rgba (fully populated)
let bg = active.defaults.background_color; // Rgba
# Ok::
For OS readers, enable the native feature (or an individual kde / portal
/ macos / windows) — see Feature flags below. No features
are needed to use bundled presets.
Core concepts
-
Theme— sparse, TOML-shaped definition (fields areOption<T>). Load viaTheme::preset(…),Theme::from_toml(…), orTheme::from_file(…). -
ResolvedTheme— fully-populated variant where every field has a value. Safe to hand to UI code. -
ColorMode— theLight/Darkchoice passed when resolving. -
Preset — a named bundled theme. 16 ship today:
- Platform:
kde-breeze,adwaita,windows-11,macos-sonoma,material,ios - Community:
catppuccin-latte,catppuccin-frappe,catppuccin-macchiato,catppuccin-mocha,nord,dracula,gruvbox,solarized,tokyo-night,one-dark
Enumerate with
Theme::list_presets()orTheme::list_presets_for_platform(). - Platform:
Common recipes
Load a bundled preset
use ;
let theme = preset?;
let resolved = theme.resolve?;
let accent = resolved.variant.defaults.accent_color; // Rgba
# Ok::
theme.resolve(mode) returns a Resolved wrapper containing variant
(the ResolvedTheme) plus the effective icon-set and icon-theme metadata.
Layer user overrides on a preset
use Theme;
let mut theme = preset?;
let overrides = from_toml?;
theme.merge;
# Ok::
merge fills in only the fields present in the overlay; everything else stays
from the base preset.
Apply an overlay to the OS theme at runtime
use ;
let sys = from_system?;
let overlay = from_toml?;
let customised = sys.with_overlay?;
# Ok::
Cheap dark-mode poll
use system_is_dark;
if system_is_dark
Cached, does not run the full theme-reader pipeline.
Icon sets
Semantic icon roles map to platform-appropriate glyphs via typed per-set loaders:
use ;
use IconRole;
// Bundled set (no system dependencies).
let copy = new.load;
// System icon theme on Linux (reads the active theme, e.g. breeze-dark).
let sys = new
.theme
.load;
Animated spinners respect the OS prefers-reduced-motion preference:
use MaterialLoader;
use prefers_reduced_motion;
if let Some = load_indicator
Connector crates provide toolkit playback helpers (see the native-theme-gpui
and native-theme-iced READMEs).
Feature flags
[]
= { = "0.5", = ["native"] }
native is a meta-feature enabling every OS reader for the current target
(kde + portal + macos + windows). Individual features:
| Feature | Role |
|---|---|
kde / portal / macos / windows |
Platform-specific theme readers |
linux |
Meta-feature: kde + portal |
watch |
Runtime theme-change notifications |
system-icons |
Linux freedesktop icon-theme lookups |
material-icons / lucide-icons |
Bundle those icon sets |
svg-rasterize |
Rasterize SVG icons to RGBA via resvg |
OS-specific dependencies are target-gated — native on macOS only pulls in
macOS-related deps.
Links
- API reference on docs.rs
- Connectors:
native-theme-gpui,native-theme-iced - Showcase examples
- CHANGELOG
License
Licensed under any of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be triple licensed as above, without any additional terms or conditions.