Senren UI

Foundations

Conventions

A short, opinionated list. Follow these and Senren stays predictable for both humans and AI agents.

Hard rules #

  1. 01 Use Senren components before writing custom HTML for the same purpose.
  2. 02 Server-render via ViewComponent. Stimulus only for local behavior.
  3. 03 Turbo handles server state. Controllers do not fetch/XHR from JS.
  4. 04 No React, Vue, Alpine, lit, or external state framework. Ever.
  5. 05 Tailwind classes must use semantic tokens (bg-[hsl(var(--senren-background))], text-[hsl(var(--senren-foreground))], border-[hsl(var(--senren-border))]). Never hard-code gray-*, slate-*, zinc-*.
  6. 06 Every component root carries data-senren-component="" for tests and DOM inspection.
  7. 07 Render with parens when passing inline content blocks. Ruby precedence makes render Senren::Foo.new(args) { "bar" } attach the block to .new, not render.

Adding custom classes #

Every Senren component accepts class_name: as the canonical extension point. Your classes are merged last, so they always win.

ERB
<%# Add Tailwind classes via class_name: on any Senren component. %>
<%= render(Senren::ButtonComponent.new(variant: :primary, class_name: "shadow-sm")) { "Save" } %>

<%= render Senren::CardComponent.new(class_name: "max-w-3xl mx-auto") do |c| %>
  <% c.with_body { "..." } %>
<% end %>

Slots #

Composite components (Card, Dialog, AlertDialog, DropdownMenu, Sidebar, DataTable) use ViewComponent slots.

ERB
<%= render Senren::CardComponent.new do |card| %>
  <% card.with_header do %>
    <%= render(Senren::TypographyComponent.new(variant: :h3)) { "Profile" } %>
  <% end %>
  <% card.with_body do %>
    <%= render Senren::AvatarComponent.new(initials: "AS") %>
  <% end %>
<% end %>

File ownership #

app/components/senren/** Your app — edit freely after install
app/javascript/controllers/senren/** Your app — edit freely after install
app/assets/stylesheets/senren.css Your app — re-skin tokens
.senren/skill.md Generated region only (between markers)
.senren/registry.yml Generator (mirror of gem registry)
.senren/installed_components.yml Generator (ledger)
.senren/conventions.md This file — safe to edit
public/llms.txt, public/llms-full.txt Generator (do not edit)