Stimulus Composition
Your Templates Tell a Story
Stimulus composition is the pattern of separating javascript behavior into isolated, reusable controllers that coordinate through events.
I’m a big advocate of this approach. Small, reusable, single responsibility controllers are much easier to reason about and change than are large, coupled, multifaceted ones.
That’s pretty obvious, in my opinion. There is another benefit to this approach that is much more subtle, but makes a profound impact.
When done well, controller composition leads to highly declarative code. Where the view templates serve as documentation for the behavior of the page and the actual JavaScript code can be treated as implementation detail and largely ignored.
Get Andy Cohen’s stories in your inbox
Join Medium for free to get updates from this writer.
The following template is contrived, but illustrates my point.
<div data-controller="calculator reportGenerator pdfRenderer">
<div data-action="calculator:result->reportGenerator#perform reportGenerator:result->pdfRenderer#perform">
<input data-calculator-target="input" />
<input data-calculator-target="input" />
<button data-action="calculator#perform" data-calculator-operation-param="add">+</button>
<button data-action="calculator#perform" data-calculator-operation-param="subtract">-</button>
<button data-action="calculator#perform" data-calculator-operation-param="multiply">*</button>
<canvas data-pdf-renderer-target="output"></canvas>
</div>
</div>It clearly documents not only the behavior of the page and how the user interacts with it, but also the components involved and how they relate to each other.
Let’s say you’re investigating a rendering bug. Which Javascript file do you probably need to look at?
Let’s say you’ve been asked to add support for division. How would you do that?
This pattern isn’t perfect. Over time it can negatively impact template readability due to an explosive accumulation of HTML attributes. There is a point where the very benefit I mentioned above becomes a liability.
This is a problem I’m thinking a lot about lately and will be the topic of a future post, once I’ve organized my thoughts. Thanks for reading!






