Shadwire

Search the documentation

Search the documentation and component pages by title and by content.

Get started
Introduction
Installation
shadwire.json
Theming
Dark mode
Tools
CLI
Agent skill
Registry
llms.txt
Guides
Composition
Styling
Forms
Icons
Accessibility
Localisation
Blocks
Overview
Components
Overview
Accordion
Alert
Alert Dialog
Aspect Ratio
Avatar
Badge
Breadcrumb
Button
Button Group
Calendar
Card
Carousel
Chart
Checkbox
Collapsible
Combobox
Command
Context Menu
Data Table
Date Picker
Dialog
Drawer
Dropdown Menu
Empty
Field
Hover Card
Icon
Input
Input Group
Input OTP
Item
Kbd
Label
Menubar
Native Select
Navigation Menu
Pagination
Popover
Progress
Radio Group
Resizable
Scroll Area
Select
Separator
Sheet
Sidebar
Skeleton
Slider
Sonner
Spinner
Switch
Table
Tabs
Textarea
Toggle
Toggle Group
Tooltip

Installation

Install the CLI, run init once, and start adding components.

Requirements

The installed components only need what a Rails app usually has. These are the minimum versions:

Requirement Version Why
ruby >= 3.2 The syntax the components and the CLI use.
rails >= 7.1 View helpers, the tag builder and the asset pipeline.
view_component >= 4.0 The components are ViewComponent classes.
lucide-rails >= 0.7 The Rails port of Lucide, shadcn/ui's icon set.
Tailwind CSS v4 The tokens use @theme inline, which is v4.

Install the CLI

The CLI is only used during development, never at runtime. You can install it globally or add it to the app.

# global
gem install shadwire

# or straight into the app, in the development group
bundle add shadwire --group development

Run init

Run it from the root of the Rails app. It is the only command you run without bin/, because it is the one that creates the binstub the other commands use.

shadwire init                     # gem installed globally
bundle exec shadwire init         # gem in the Gemfile

What it does:

  • shadwire.json: writes the manifest at the app root: the registry URL, where each kind of file goes, the Tailwind entrypoint, and what is installed.
  • Base files: installs app/components/ui_component.rb (the shared superclass) and vendor/shadwire/shadwire.css (the tokens).
  • Base gems: adds view_component and lucide-rails to the Gemfile if they are missing.
  • development group: adds shadwire itself to the Gemfile's development group.
  • bin/shadwire: writes the binstub you run the CLI with from then on. It loads the CLI from the app's bundle.
  • Tailwind @import: imports shadwire.css in the Tailwind entrypoint.

Running it again is safe: it does not undo anything, and it leaves an existing binstub alone. --force resets shadwire.json and rewrites the binstub.

Why bin/shadwire

After init, run every command through bin/shadwire. The binstub loads the CLI from the app's bundle, so everyone on the project runs the same version, whatever they have installed globally.

Add your first component

bin/shadwire add button

The components it depends on are installed along with it. Each component also installs its own helper module (button writes app/helpers/ui/button_helper.rb), and Rails includes everything under app/helpers/ in your views with no include.

<%= ui_button(variant: :outline, size: :sm) { "Save" } %>

<%= render Ui::ButtonComponent.new(variant: :outline, size: :sm) do %>
  Save
<% end %>

Both forms render the same thing. In views, the helper is shorter.

Confirm it worked

bin/shadwire status

status never fails. Outside a Rails app it reports "rails": false, an unreachable registry shows up as registryError and an unreadable shadwire.json as configError, and the exit code is always 0. The CLI page lists every field.

Without the CLI

You can copy the files by hand from the published registry or from llms-full.txt, but then shadwire.json does not know about them, and diff, update and remove rely on it. Use the CLI when you can.