Installation
View SourceThis guide walks you through setting up Sutra UI in your Phoenix application.
Prerequisites
Sutra UI requires:
| Dependency | Minimum Version | Notes |
|---|---|---|
| Elixir | 1.20+ | Matches the package constraint |
| Phoenix | 1.8+ | Required for colocated hooks |
| Phoenix LiveView | 1.2+ | Current supported LiveView line |
| Tailwind CSS | v4 | CSS-first configuration |
Why Phoenix 1.8+?
Sutra UI uses colocated hooks - a Phoenix 1.8+ feature that allows JavaScript hooks to live alongside their components. Runtime hooks need no app-side hook file; extracted hooks are merged into LiveSocket.
Step 1: Add Dependencies
Add sutra_ui to your dependencies in mix.exs:
def deps do
[
{:sutra_ui, "~> 0.4.0"}
]
endThen fetch dependencies:
mix deps.get
Step 2: Run the Installer
mix sutra_ui.install
This will:
- Add
@sourceand@importlines to yourassets/css/app.css - Add
use SutraUIto thehtml_helpersfunction in your web module
The installer will also warn you if core_components.ex still exists (see Step 3).
Manual CSS setup
If the installer can't find your app.css or you prefer to do it manually, add these lines to assets/css/app.css:
@import "tailwindcss";
/* Add Sutra UI source paths for Tailwind to scan */
@source "../../deps/sutra_ui/lib";
/* Import Sutra UI component styles */
@import "../../deps/sutra_ui/priv/static/sutra_ui.css";
/* Your app's custom styles below... */Step 3: Delete core_components.ex
Sutra UI replaces Phoenix's generated button, input, flash, and related UI helpers.
It does not provide a general icon/1 helper or bundled icon set. If your app
uses Phoenix's generated <.icon>, move that helper to a separate module or
replace those calls before deleting core_components.ex.
Icons Are App-Owned
Sutra components include internal SVGs only where the component owns the icon.
For application UI, use your app's existing icon helper or inline accessible
SVG. Do not use SutraUI.Icon; it is not a Sutra API.
Delete the generated file:
rm lib/my_app_web/components/core_components.ex
Then remove the import from your lib/my_app_web.ex:
defmodule MyAppWeb do
# ...
defp html_helpers do
quote do
# Remove or comment out this line:
# import MyAppWeb.CoreComponents
use SutraUI # Already added by the installer
# ... other imports
end
end
endWhy delete core_components?
Phoenix generates core_components.ex with basic UI components. Sutra UI provides enhanced versions of all these components plus 50+ more. Keeping both would cause naming conflicts and confusion.
Step 4: Colocated Hooks
Sutra UI uses Phoenix 1.8+ colocated hooks. Most hooks load at runtime.
Some components, such as dialog and animated response, use extracted hooks.
Merge the generated Sutra UI hooks into your LiveSocket:
import {hooks as sutraUiHooks} from "phoenix-colocated/sutra_ui"
const liveSocket = new LiveSocket("/live", Socket, {
hooks: {...sutraUiHooks}
})Deployment Note
Runtime hooks are still compiled with your app code. Ensure your deployment runs mix compile before assets.deploy:
# mix.exs
"assets.deploy": [
"compile", # Must come first
"esbuild my_app --minify",
"tailwind my_app --minify",
"phx.digest"
]Step 5: Verify Installation
Create a simple test to verify everything works:
<.button>Hello Sutra UI!</.button>
<.button variant="destructive">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mr-2 size-4" aria-hidden="true"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/><line x1="10" x2="10" y1="11" y2="17"/><line x1="14" x2="14" y1="11" y2="17"/></svg>
Delete
</.button>
<.button variant="outline" size="sm">Small Outline</.button>If you see styled buttons, you're ready to go!
Troubleshooting
Components render but have no styles
Cause: Tailwind isn't scanning the Sutra UI source files.
Fix: Ensure you have the @source directive in your app.css:
@source "../../deps/sutra_ui/lib";Then restart your Phoenix server and asset watcher.
"undefined function" errors for components
Cause: Components not imported.
Fix: Add use SutraUI to your html_helpers or import specific components.
Conflicts with core_components
Cause: Both core_components.ex and Sutra UI define components like button/1, input/1, etc.
Fix: Delete lib/my_app_web/components/core_components.ex and remove its import from your web module (see Step 3).
Hook-based components don't work (Select, Dialog, Tabs, etc.)
Cause: Colocated hooks require Phoenix 1.8+.
Fix: Upgrade Phoenix:
# mix.exs
{:phoenix, "~> 1.8"}Then run:
mix deps.update phoenix
If only extracted-hook components such as dialog or animated response fail,
check that phoenix-colocated/sutra_ui hooks are merged into your LiveSocket.
CSS variables not applying
Cause: Sutra UI styles not imported or loaded after your overrides.
Fix: Ensure the import order is correct:
@import "tailwindcss";
@source "../../deps/sutra_ui/lib";
@import "../../deps/sutra_ui/priv/static/sutra_ui.css";
/* Your overrides AFTER sutra_ui.css */
:root {
--primary: oklch(0.65 0.20 145);
}Dark mode not working
Cause: Missing dark class on <html> element.
Fix: Add the theme switcher with the root-layout listener from
SutraUI.ThemeSwitcher, or manually toggle the class:
<.theme_switcher id="theme-toggle" />Or control it manually:
document.documentElement.classList.toggle('dark')Next Steps
- Live Demo - Browse components and examples
- Theming Guide - Customize colors and styles
- Components Cheatsheet - Quick reference for all components
- JavaScript Hooks - Understanding colocated hooks