egui-shadcn: Beautiful UI Components for Rust

TL;DR

I built egui-shadcn, an open-source Rust library that brings shadcn/ui-style components to egui. It ships 55+ widgets with built-in light and dark theming, 1600+ Lucide icons, and works on desktop, web, and anywhere egui runs.

Try the live demo (runs in your browser via WebAssembly).

Why?

egui is one of the best immediate-mode GUI libraries out there. It's fast, portable, and the API is delightful. But the default look is... utilitarian. If you want your egui app to look polished — with proper spacing, rounded corners, hover states, focus rings, and a consistent design language — you end up writing a lot of styling code.

Meanwhile, in the web world, shadcn/ui solved exactly this problem for React. Beautiful, accessible, composable components that just look right out of the box. I wanted that same experience in Rust.

What's Inside

The library is a single egui-shadcn crate with zero runtime dependencies beyond egui itself (plus egui_flex for flexbox layout). Here's the component breakdown:

Inputs: Button, Checkbox, Input, InputOtp, Radio, RadioGroup, Select, Slider, Switch, Textarea, Toggle, ToggleGroup, Combobox, DatePicker

Layout: Accordion, AspectRatio, Card, Collapsible, Resizable, ScrollArea, Separator, Tabs, Flex

Overlays: AlertDialog, Command, ContextMenu, Dialog, Drawer, DropdownMenu, HoverCard, Menubar, NavigationMenu, Popover, Sheet, Tooltip

Feedback: Alert, Badge, Progress, Skeleton, Spinner, Toast

Data: Avatar, Breadcrumb, Calendar, Carousel, Pagination, Sidebar, Table

Typography: Typography, Label, Kbd

Icons: 1600+ Lucide icons rendered as vector paths

Quick Start

[dependencies]
egui-shadcn = "0.1"
// Set up the theme
let theme = egui_shadcn::theme::shadcn_theme_dark::dark();
egui_shadcn::ShadcnThemeExt::set_shadcn_theme(ctx, theme);

// Use components
egui_shadcn::Button::new("Click me").show(ui);

ui.add(egui_shadcn::Switch::new(&mut value).label("Dark mode"));

ui.add(egui_shadcn::Input::new(&mut text).placeholder("Type here..."));

ui.add(egui_shadcn::Select::new(&mut selected, &options)
    .placeholder("Pick one..."));

Each component follows egui conventions — either implement egui::Widget for use with ui.add(), or provide a .show(ui) builder pattern.

Theming

The library comes with light and dark themes built in. Switching is a single line:

let theme = if dark_mode {
    egui_shadcn::theme::shadcn_theme_dark::dark()
} else {
    egui_shadcn::theme::shadcn_theme_light::light()
};
egui_shadcn::ShadcnThemeExt::set_shadcn_theme(ctx, theme);

The theme covers all components — backgrounds, borders, foreground colors, accent states, destructive variants, muted text, and more. Every color is defined in a single ShadcnTheme struct, so creating your own theme is straightforward.

Flexbox Layout

One thing I missed from web development was proper flexbox. The library wraps egui_flex with a simpler API:

// Row with gap, grow, and justify
egui_shadcn::Flex::row().gap(8.0).w_full().show(ui, |f| {
    f.grow(1.0, egui_shadcn::Input::new(&mut text)
        .placeholder("Type a message..."));
    f.add(egui_shadcn::Button::new("Send"));
});

// Wrapping tags
egui_shadcn::Flex::row().gap(4.0).wrap().show(ui, |f| {
    for tag in &tags {
        f.add(egui_shadcn::Badge::new(*tag));
    }
});

Icons

All 1600+ Lucide icons are embedded as SVG path data and rendered as vector strokes at any size:

let (rect, _) = ui.allocate_exact_size(
    egui::vec2(24.0, 24.0), egui::Sense::hover()
);
egui_shadcn::paint_icon(
    ui.painter(), rect,
    &egui_shadcn::LucideIcon::Heart,
    theme.foreground,
);

Buttons can also take icons directly:

egui_shadcn::Button::new("Download")
    .icon(egui_shadcn::LucideIcon::Download)
    .show(ui);

egui_shadcn::Button::icon_only(egui_shadcn::LucideIcon::Settings)
    .variant(egui_shadcn::ButtonVariant::Outline)
    .show(ui);

WebAssembly

The whole thing compiles to WebAssembly and runs in the browser. The live demo is a full interactive showcase of every component — buttons, inputs, dialogs, toasts, calendars, the icon browser, everything. It's about 3.6 MB of wasm.

Getting Started

cargo add egui-shadcn

Then check out the examples:

cargo run --example demo
cargo run --example shadcn_demo
cargo run --example component_dashboard

The source is on GitHub. Contributions welcome.