
A Claude Code plugin that teaches Claude how to build UIs with **maquina_components** — ERB partials styled with Tailwind CSS 4 and data attributes, inspired by shadcn/ui.

---

## What Is This?

A Claude Code skill that provides:

- **Component catalog** — All 15+ components with ERB examples
- **Form patterns** — Validation, error handling, inline layouts
- **Layout patterns** — Sidebar navigation, page structure
- **Turbo integration** — Frames, Streams, component updates
- **Spec checklist** — Review criteria for UI quality

When installed, Claude generates code that matches your component conventions without back-and-forth corrections.

---

## The Problem It Solves

Without the skill, asking Claude to build a view results in generic Rails patterns:

```erb
<div class="card">
  <h2><%%= @user.name %></h2>
</div>
```

With the skill, Claude uses your actual components:

```erb
<%%= render "components/card" do %>
  <%%= render "components/card/header" do %>
    <%%= render "components/card/title", text: @user.name %>
  <%% end %>
<%% end %>
```

The skill eliminates the "use the card partial, not a div" corrections that slow down AI-assisted development.

---

## Quick Start

### 1. Add the Marketplace

```bash
/plugin marketplace add maquina-app/rails-claude-code
```

### 2. Install the Plugin

```bash
/plugin install maquina-ui-standards@maquina
```

### 3. Start Building

```
> Create the users index view with a table showing name, email, and status
```

---

## Requirements

The [maquina_components gem](https://github.com/maquina-app/maquina_components) must be installed in your Rails application:

```bash
bundle add maquina_components
rails generate maquina_components:install
```

---

## What It Provides

| Reference | Purpose |
|-----------|---------|
| Component catalog | All available components with ERB examples |
| Form patterns | Validation states, error handling, inline layouts |
| Layout patterns | Sidebar navigation, page headers, content areas |
| Turbo integration | Frames, Streams, and component updates |
| Spec checklist | Accessibility and consistency review criteria |
| Helpers reference | Ruby helpers provided by maquina_components |
| Stimulus controllers | Controllers shipped with the component library |
| Installation guide | Setup for existing and new Rails applications |

As of **v0.5.0** the plugin ships as a model-invoked **skill** instead of a subagent: Claude loads the standards into the same conversation where your feature is being built — with your models, controllers, and spec in context — rather than delegating view work to an isolated agent. The trigger works the same way; the skill activates when UI work starts. This release also syncs the references with maquina_components 0.5.x: the Drawer component, the Stats grid, vocabulary aliases (`:destructive`/`:error`, size `:default`), `text:`/`content:` leaf parameters, and the ability to attach your own Stimulus controllers to any component (`data-controller` values concatenate instead of being replaced).

> **On maquina_components 0.6.0.** The bundled references still describe 0.5.x. What they say about component APIs still holds, but they predate the token layer and the move of engine CSS into `@layer components` — so they do not cover the shape, elevation, focus and weight tokens, the new drawer and sidebar parts, or the fact that utility classes passed through `css_classes:` now win where they used to be swallowed. Read [Theming](/documentation/components/theming/) and [Upgrading](/documentation/components/upgrading/) alongside them until the references catch up.

---

## Usage Examples

### Create a View

```
> Create the users index view with a table showing name, email, and status
```

Claude generates:

```erb
<%%= render "components/page_header", title: "Users", description: "Manage team members" %>

<%%= render "components/card" do %>
  <%%= render "components/card/content" do %>
    <table data-component="table">
      <thead>
        <tr>
          <th>Name</th>
          <th>Email</th>
          <th>Status</th>
        </tr>
      </thead>
      <tbody>
        <%% @users.each do |user| %>
          <tr>
            <td><%%= user.name %></td>
            <td><%%= user.email %></td>
            <td>
              <%%= render "components/badge",
                variant: user.active? ? :success : :secondary do %>
                <%%= user.active? ? "Active" : "Inactive" %>
              <%% end %>
            </td>
          </tr>
        <%% end %>
      </tbody>
    </table>
  <%% end %>
<%% end %>
```

### Implement a Form

```
> Implement the project form with name, description, and a framework combobox
```

Claude generates:

```erb
<%%= form_with model: @project do |form| %>
  <div class="space-y-4">
    <div>
      <%%= form.label :name %>
      <%%= form.text_field :name, data: { component: "input" } %>
    </div>

    <div>
      <%%= form.label :description %>
      <%%= form.text_area :description, data: { component: "textarea" }, rows: 4 %>
    </div>

    <div>
      <%%= form.label :framework_id %>
      <%%= combobox_simple name: "project[framework_id]",
            value: @project.framework_id,
            options: @frameworks.map { |f| { value: f.id, label: f.name } },
            placeholder: "Select a framework" %>
    </div>

    <div class="flex justify-end gap-2">
      <%%= link_to "Cancel", projects_path,
        data: { component: "button", variant: "outline" } %>
      <%%= form.submit "Save",
        data: { component: "button", variant: "primary" } %>
    </div>
  </div>
<%% end %>
```

### Review Existing Code

```
> Review this view against the maquina UI standards and suggest improvements
```

Claude checks for:
- Proper component usage instead of raw HTML
- Correct data attributes on form fields
- Accessibility attributes
- Consistent spacing and layout patterns
- Turbo Frame and Stream integration

---

## Component Patterns

### Partial Components

Components rendered as partials with strict locals:

```erb
<%%# Card with header and content %>
<%%= render "components/card" do %>
  <%%= render "components/card/header" do %>
    <%%= render "components/card/title", text: "Appointments" %>
    <%%= render "components/card/description", text: "Manage your schedule" %>
  <%% end %>
  <%%= render "components/card/content" do %>
    <!-- Content here -->
  <%% end %>
<%% end %>
```

### Data Attribute Components

Form elements and buttons use data attributes for styling:

```erb
<%%# Text input %>
<%%= form.text_field :name, data: { component: "input" } %>

<%%# Button %>
<%%= link_to "Edit", edit_path,
  data: { component: "button", variant: "outline", size: "sm" } %>

<%%# Badge %>
<%%= render "components/badge", variant: :success do %>
  Active
<%% end %>
```

### Layout Patterns

```erb
<%%# Sidebar layout %>
<%%= render "components/sidebar/provider", state: sidebar_state do %>
  <%%= render "components/sidebar" do %>
    <%%= render "components/sidebar/header" do %>
      <!-- Logo -->
    <%% end %>
    <%%= render "components/sidebar/content" do %>
      <%%= render "components/sidebar/group", title: "Navigation" do %>
        <%%= render "components/sidebar/menu" do %>
          <%%= render "components/sidebar/menu_item" do %>
            <%%= render "components/sidebar/menu_button",
              url: dashboard_path,
              icon_name: :home,
              title: "Dashboard",
              active: current_page?(dashboard_path) %>
          <%% end %>
        <%% end %>
      <%% end %>
    <%% end %>
  <%% end %>

  <%%= render "components/sidebar/inset" do %>
    <%%= yield %>
  <%% end %>
<%% end %>
```

---

## Package Contents

```
maquina-ui-standards/
├── skills/ui/SKILL.md                 # Model-invoked skill
├── QUICKSTART.md                      # Quick reference for humans
└── references/
    ├── component-catalog.md           # All available components
    ├── form-patterns.md               # Validation, error handling
    ├── layout-patterns.md             # Pages, dashboards
    ├── turbo-integration.md           # Frames, streams
    ├── spec-checklist.md              # Accessibility, consistency
    ├── helpers-reference.md           # Ruby helpers provided by maquina_components
    ├── stimulus-controllers.md        # Controllers shipped with the library
    └── installation-guide.md          # Setup for existing and new Rails apps
```

---

## Team Installation

Add to your project's `.claude/settings.json`:

```json
{
  "extraKnownMarketplaces": {
    "maquina": {
      "source": {
        "source": "github",
        "repo": "maquina-app/rails-claude-code"
      }
    }
  },
  "enabledPlugins": [
    "maquina-ui-standards@maquina"
  ]
}
```

---

## Alternative: Claude Skill Installation

If you prefer using Claude Skills instead of the plugin system, copy the skill to your project:

```bash
mkdir -p .claude/skills
# Copy from the rails-claude-code repository
cp -r maquina-ui-standards/skills/ui .claude/skills/maquina-ui-standards
cp -r maquina-ui-standards/references .claude/skills/
```

Then reference it in your `CLAUDE.md`:

```markdown
## UI Components

This project uses maquina_components for UI. Before implementing views,
forms, or interactive components, read the UI standards skill:

.claude/skills/maquina-ui-standards/SKILL.md

Always consult the skill when:
- Creating or modifying views
- Implementing forms
- Adding interactive components
- Building layouts with sidebar/header patterns
- Working with Turbo Streams that update UI
```

---

## Next Steps

<div class="not-prose mt-8 grid grid-cols-1 gap-4 sm:grid-cols-2">
  <a href="https://github.com/maquina-app/rails-claude-code" target="_blank" rel="noopener" class="group relative rounded-2xl border border-zinc-200 p-6 hover:border-[#50B1FD]/50 dark:border-zinc-800 dark:hover:border-[#50B1FD]/50 transition">
    <h3 class="font-sora font-semibold text-zinc-900 dark:text-white group-hover:text-[#50B1FD] transition">
      GitHub Repository
    </h3>
    <p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
      View source code and contribute.
    </p>
  </a>

  <a href="/documentation/components/" class="group relative rounded-2xl border border-zinc-200 p-6 hover:border-[#50B1FD]/50 dark:border-zinc-800 dark:hover:border-[#50B1FD]/50 transition">
    <h3 class="font-sora font-semibold text-zinc-900 dark:text-white group-hover:text-[#50B1FD] transition">
      Component Documentation
    </h3>
    <p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
      Browse all maquina_components.
    </p>
  </a>

  <a href="/blog/2026/01/claude-skill-for-maquina-components/" class="group relative rounded-2xl border border-zinc-200 p-6 hover:border-[#50B1FD]/50 dark:border-zinc-800 dark:hover:border-[#50B1FD]/50 transition">
    <h3 class="font-sora font-semibold text-zinc-900 dark:text-white group-hover:text-[#50B1FD] transition">
      Announcement Post
    </h3>
    <p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
      Read about the skill's development.
    </p>
  </a>

  <a href="https://github.com/maquina-app/maquina_components" target="_blank" rel="noopener" class="group relative rounded-2xl border border-zinc-200 p-6 hover:border-[#50B1FD]/50 dark:border-zinc-800 dark:hover:border-[#50B1FD]/50 transition">
    <h3 class="font-sora font-semibold text-zinc-900 dark:text-white group-hover:text-[#50B1FD] transition">
      maquina_components Gem
    </h3>
    <p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
      Install the component library.
    </p>
  </a>
</div>
