
A Claude Code plugin that applies opinionated **StimulusJS best practices** sourced from [betterstimulus.com](https://www.betterstimulus.com). Use it whenever writing, reviewing, debugging, or refactoring Stimulus controllers.

---

## What Is This?

A Claude Code skill that:

- **Writes** Stimulus controllers that follow the Values API, Classes API, and Outlets patterns
- **Reviews** existing controllers against a concrete best-practices checklist
- **Refactors** anti-patterns such as hardcoded selectors, instance-variable state, and manual `addEventListener` calls
- **Applies** SOLID principles adapted to Stimulus (Single Responsibility, Open-Closed, Dependency Inversion)
- **Integrates** with Turbo — teardown before caching, restoring DOM state, form interception

The skill is triggered by mentions of `data-controller`, `data-action`, `data-target`, `data-values`, outlets, lifecycle callbacks, Hotwire patterns, or Turbo-and-Stimulus integration.

---

## Quick Start

### 1. Add the Marketplace

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

### 2. Install the Plugin

```bash
/plugin install better-stimulus@maquina
```

### 3. Ask for a Review or Refactor

```
> Review my dropdown_controller.js against Stimulus best practices
> Refactor this controller to use the Values API instead of instance variables
> Write a Stimulus controller that toggles a panel with late binding
```

---

## What It Enforces

| Area | Best Practice |
|------|--------------|
| State | Use the Values API as the single source of truth, not instance variables |
| CSS classes | Store in `static classes`, never hardcode strings |
| Events | Declare in `data-action` markup, not `addEventListener` in `connect()` |
| Dependencies | Late binding via Values / Classes / dataset — no hardcoded selectors |
| Composition | Prefer mixins for roles, inheritance only for specializations |
| Inter-controller | Outlets for direct calls, custom events for broadcast |
| Third-party libs | Initialize in `connect()`, destroy in `disconnect()` |
| Turbo | Implement `teardown()` wired to `turbo:before-cache` when mutating DOM |
| SRP | Split controllers that act on both `this.element` and targets |

A full pre-commit checklist ships with the plugin so Claude can verify any new controller before handing it back.

---

## Usage Examples

### Review an Existing Controller

```
> Review app/javascript/controllers/modal_controller.js
```

The skill checks for state in instance variables, hardcoded CSS classes, manual event listeners, mixed `element`/`target` responsibilities, and missing Turbo teardown.

### Refactor Toward the Values API

```
> Refactor this controller so state lives in values, not this.open
```

The skill moves state into `static values`, adds a `*ValueChanged` callback, and updates markup to include the new data attributes.

### Write a New Controller with Late Binding

```
> Write a toggle controller that uses data-toggle-active-class for styling
```

The skill produces a controller that reads its active class via the Classes API so the same code works anywhere the markup declares a class.

### Apply Hotwire Patterns

```
> This controller mutates the DOM — add a teardown for Turbo caching
```

The skill adds a `teardown()` method and wires it to `turbo:before-cache` at the application level.

---

## Reference Material

The plugin ships with two reference files the skill consults on demand:

| Reference | Purpose |
|-----------|---------|
| `references/cookbook.md` | Copy-paste-ready controllers: faceted search, refresh-when-visible, auto sort, dark mode, radio dropdown |
| `references/solid.md` | SOLID principles adapted to Stimulus with examples and rationale |

---

## Package Contents

```
better-stimulus/
└── skills/better-stimulus/
    ├── SKILL.md                    # Main skill
    └── references/
        ├── cookbook.md             # Ready-to-use controller patterns
        ├── inter-controller.md     # Outlets, callbacks, custom events
        ├── error-handling.md       # Global error handler
        └── solid.md                # SOLID principles for Stimulus
```

---

## Team Installation

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

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

---

## 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="https://www.betterstimulus.com" 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">
      betterstimulus.com
    </h3>
    <p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
      The original collection of Stimulus best practices.
    </p>
  </a>

  <a href="/documentation/ai-tools/maquina-ui-standards/" 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 UI Standards
    </h3>
    <p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
      Pair with component-level UI guidance.
    </p>
  </a>
</div>
