Actionable ideas for Ruby and Stimulus developers.

Read this first

Introducing stimulus-shortcut

No shortcuts.

Hot on the heels of stimulus-hotkeys, I am thrilled to release stimulus-shortcut, “a Stimulus controller for mapping keystrokes to element events”.

Based on the preview version of Stimulus 2.0, stimulus-hotkeys wraps the amazing HotKeys.js library and takes advantage of the new Stimulus Values API to bind the keystrokes people type to the default events of elements on your page.

Let’s look at a simple example, in which the user hits the “p” key and it makes the link click itself.

<a data-controller="shortcut" data-shortcut-key-value="p">Type 'p' to activate me!</a>

It’s a sort of sister-controller to stimulus-hotkeys in that they share dependencies and together, cover both common shortcut key patterns. They can be used happily together in the same project.

That’s about it! You can learn more on the Github project page.

Continue reading →

Introducing stimulus-hotkeys


Continuing with my mission of crafting a viable ecosystem of elegant, composable Stimulus controllers, I am pleases to unveil stimulus-hotkeys, “a Stimulus controller for mapping keystrokes to behaviors”.

Based on the preview version of Stimulus 2.0, stimulus-hotkeys wraps the amazing HotKeys.js library and takes advantage of the new Stimulus Values API to bind the keystrokes people type to functions in your controllers.

Configuration is done by providing a JSON-compliant object to the data-hotkeys-bindings-value attribute. The object keys are literally the key(s) your users will press, while the values are a mapping that resembles a Stimulus action:


Let’s look at a simple example, in which the user hits the “p” key and will see “PONG” on the console.

<div data-controller="hotkeys" 
     data-hotkeys-bindings-value='{"p": "foo->exampleping"}'></div>

Continue reading →

Introducing jquery-events-to-dom-events (and jboo)


Did you know that jQuery events aren’t events?

It’s true - and it’ll really mess up your night if you need to capture events from legacy jQuery components. Looking at you, hidden.bs.modal.

I needed a way to make $(document).trigger('fart') emit a standard $fart DOM event, so I wrote it:


This library is short and sweet, with zero dependencies - including jQuery. It’s just two functions: delegate and abnegate. It is Mutation-First; designed to work great in Stimulus and supports Turbolinks out of the box.

It even has the secret ability to listen for DOM events with jQuery event listeners, but don’t tell anyone.

You can try it now on CodePen or even better, clone a sample Rails project to experiment in a mutation-first context with Stimulus.

The Rails project is called jboo. Don’t read into the name.


Note: it is...

Continue reading →

My first npm package: stimulus-image-grid


A Stimulus controller for beautiful image grids

I published my first npm package today!


With only three optional parameters, this is a simple, drop-in, backend-agnostic, code-free solution that is completely free of CSS opinions. It’s responsive and scales to whatever bounding container you give it.

It’s also performant AF: stimulus-image-grid uses the ResizeObserver so there’s zero screen flicker. It’s compatible with Turbolinks by design and free for personal and commercial use.

Built for StimulusJS

This Stimulus controller allows you to make any configurations for the image grid directly with data attributes in your HTML. Once registered in your Stimulus application, you can use it anywhere you like.

Here is a simple example:

<div data-controller="image-grid">
  <img src="https://placehold.it/350x300/EEE04A/ffffff">

Continue reading →

Introducing Optimism: realtime remote form validation for Rails


I’m proud to announce the public release of Optimism, a new Ruby on Rails gem that makes it easy to add realtime validation error messages to your applications.

When a model validation error prevents an update from succeeding, Optimism builds a list of issues that must be resolved. This list is broadcast to the browser over a websocket connection, and the live document is changed to show the necessary validation hints. No page refreshes are required and the entire process happens faster than you can blink.

Optimism injects text content, CSS class updates and even DOM events into your page. It has no client-side scripting requirements beyond a dependency to the awesome CableReady library. It automatically handles multi-level nested forms and plays well with other technologies, such as Turbolinks.

You can try a live demo right now.

Full documentation is available here. The project...

Continue reading →

The best one-line Stimulus power move


Stimulus is a tiny and absurdly productive JavaScript framework for developers who are looking for just the right amount of structure (lifecycle events and standard HTML) without attempting to re-invent how the web works (no template rendering or routing). It is criminally underappreciated in the JavaScript community.

When using Stimulus, you write controllers in JavaScript and attach instances of those controllers to DOM elements by setting data-controller="controller-name".

Unfortunately, there’s no easy way to access methods in a controller from another controller, external scripts, jQuery plugins or the console… or is there?

Before I do the big reveal, there is technically a way to access another controller instance from inside of a controller. It’s an undocumented method so there’s no guarantee that it won’t disapper someday, but the real clue that this isn’t intended to be...

Continue reading →

Mutation-first development: a call to action


Not that long ago, someone designing a JavaScript component could rely on a simple life-cycle premise: your content would load before the jQuery embedded in the bottom of the page would come to life and initialize everything that needed initializing. The user would then click a link or hit the back button, causing the cycle to repeat itself. There was a 1:1 relationship between pages requested and load events firing.

In this era of reactive asyncronous content, that assumption is now screwing us.

Web page life-cycles continue to get more complex and the page load event is no longer a reliable singular entry point to our UI setup code. This post attempts to describe the problem and offer a strategy to fix how we create libraries and components.

We need to stop acting as though multi-stage life-cycles are edge cases. Instead, we can build idempotent libraries which support use in...

Continue reading →