Getting Started

Install Kiso and render your first component in a Rails app.

Prerequisites

  • Ruby >= 3.3 and Rails >= 8.0
  • Tailwind CSS via tailwindcss-rails or cssbundling-rails
  • A running Tailwind watcher (your Procfile.dev or bin/dev should already handle this)

Install the gem

Add Kiso to your Gemfile and bundle:

gem "kiso"
bundle install

The engine auto-registers view helpers, importmap pins, and asset paths. No additional configuration is needed to start using components.

Set up Tailwind CSS

Add one import to your Tailwind stylesheet:

/* app/assets/tailwind/application.css */
@import "tailwindcss";
@import "../builds/tailwind/kiso.css";

The kiso.css bridge file is auto-generated by tailwindcss-rails with the correct path to the engine’s CSS. Make sure your Tailwind watcher is running so the file gets created.

Set up your layout

A minimal layout that works with Kiso and dark mode:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <title>My App</title>
    <%= kiso_theme_script %>
    <%= stylesheet_link_tag "tailwind", data: { turbo_track: "reload" } %>
    <%= javascript_importmap_tags %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>

Two things to note:

  • kiso_theme_script outputs a blocking inline script that reads the user’s theme preference (localStorage, cookie, or OS setting) and sets .dark on <html> before first paint. No server-side code needed.
  • javascript_importmap_tags loads Stimulus controllers. Kiso’s controllers (for interactive components like Select, Combobox, etc.) are registered automatically via the engine.

Kiso automatically applies bg-background text-foreground antialiased to <body> via @layer base, so you don’t need to add those classes yourself. The base colors switch automatically in dark mode.

Your first component

Use the kui() helper to render any component:

<%= kui(:badge, color: :success) { "Active" } %>

Components compose from small parts. Here’s a card:

<%= kui(:card) do %>
  <%= kui(:card, :header) do %>
    <%= kui(:card, :title, text: "Team Members") %>
    <%= kui(:card, :description, text: "Manage your team.") %>
  <% end %>
  <%= kui(:card, :content) do %>
    <p>Card content goes here.</p>
  <% end %>
  <%= kui(:card, :footer) do %>
    <%= kui(:button, variant: :outline) { "Cancel" } %>
    <%= kui(:button) { "Save" } %>
  <% end %>
<% end %>

Browse all available components in the sidebar.

Icons

Lucide icons (~1,500) are bundled and work out of the box:

<%= kiso_icon("check") %>
<%= kiso_icon("settings", size: :md) %>

Add more icon libraries (Heroicons, Material Design, Tabler, etc.):

bin/kiso-icons pin heroicons

Then use them with a prefix:

<%= kiso_icon("heroicons:check-circle") %>

See Icons for the full guide on sizing, accessibility, and overriding component default icons.

Dark mode

Dark mode works out of the box when you include kiso_theme_script in your layout. Toggle it with the color mode components:

<%= kui(:color_mode_button) %>

Or use the three-way select (Light / Dark / System):

<%= kui(:color_mode_select) %>

See Dark Mode & Theming for details on how the token system works and how to customize the palette.

Bundler apps (esbuild, Vite, Bun)

If your app uses a JavaScript bundler instead of importmaps, install the npm package:

npm install kiso-ui

Register the controllers in your Stimulus application:

import KisoUi from "kiso-ui"
KisoUi.start(application)

Importmap apps get Stimulus controllers automatically — no npm install needed.

Customization

Kiso works out of the box with sensible defaults. When you’re ready to customize, there are three levels:

Per-instance — pass css_classes: to override styles on a single usage:

<%= kui(:button, css_classes: "w-full rounded-full") { "Wide pill button" } %>

Per-component globally — override theme defaults for every instance of a component via an initializer:

# config/initializers/kiso.rb
Kiso.configure do |config|
  config.theme[:button] = { base: "rounded-full" }
  config.theme[:badge] = { defaults: { variant: :outline } }
end

Per-token — override CSS custom properties to match your brand:

@theme {
  --color-primary: var(--color-violet-600);
  --color-primary-foreground: var(--color-white);
}

See Customizing Components for the full guide.