Hotwire: Turbo and Stimulus in a nutshell

Sofia Sousa
3 min readAug 9, 2022

--

Hotwire stands for “HTML over the wire” and the goal is to build client-side interactivity without writing (much) JavaScript. For that, Turbo manages HTML requests to the server and directs responses, and Stimulus - a minimal JavaScript library - manages the interactions that Turbo can’t handle.

Turbo

The Turbo Drives (old Turbolinks) captures all link clicks and form submissions, and extracts the body from the response in order to replace it in the existing page. Behind the scenes, it also does some work to keep the browser back button working and manages caches.

Hotwire Turbo Drives
Instead of reloading the entire page, Turbo Drives only replaces the Body section

A Turbo Frame is a custom HTML tag (<turbo-frame id="ID">) that allows a small part of the page to behave the way Turbo Drives treats the entire page.

The turbo-rails gem provides the turbo_frame_tag helper that generates a custom <turbo-frame> HTML element with the given id and the contents coming from the block

In summary, with Turbo Frames:

  • A response can only change one DOM element.
  • A response will update the inner HTML of the element.
  • The affected element must be a turbo-frame with the same DOM id.
  • Turbo Frames are evaluated on any navigation inside a turbo-frame element.

A Turbo Stream is another custom HTML tag (<turbo-stream action="ACTION" target="TARGET">) that allows multiple parts of the page to be updated from a single request. They are also designed to work with WebSockets via ActionCable.

turbo_stream.<action> helpers are also provided by the turbo-rails gem. The first argument is the target DOM id and the remaining arguments are passed through to render

In summary, with Turbo Streams:

  • A response can change multiple DOM elements.
  • A response can append, prepend, remove, replace, update or insert content before or after the affected elements.
  • Affected elements can be any type of HTML with a matching DOM id (turbo-stream target).
  • Turbo Streams are evaluated on form responses or Action Cable broadcast.

Stimulus

Stimulus is particularly good for interactions that are relatively small and are expansions of existing browser capabilities. A few concepts that describe how HTML markup relates to the JavaScript code:

  • Controllers are where the Stimulus JavaScript code goes. They are invoked by adding the data-controller="controller-name" (dash-case) attribute to the DOM element and they contain methods that are called in response to events that happen.
  • Actions connect a DOM event to the controller code that is executed when the event happens. The data-action="event->controller-name#actionName" is the attribute name that signs to Stimulus that an action is being defined.
  • Targets are DOM elements used by controllers to determine the state of the page or to be changed according to the state of the page. They are identified by the attribute named data-<controller-name>-target="targetName". Stimulus defines three properties on the controller for target elements: <targetName>Target, <targetName>Targets and has<targetName>Target .
  • Data maps and values are the state that is stored in the DOM. The attribute name for values is data-<controller-name>-<attribute-name>-value="value". The allowed types for values are Array, Boolean, Number, Object or String. For non-array values, Stimulus creates <attributeName>Value and has<attributeName>Value properties. Same for arrays but in plural: <attributeName>Values and has<attributeName>Values.
  • Classes: CSS classes that represent the state. The name of the data attribute has the form data-<controller-name>-<description>-class="class". As expected, Stimulus creates a few properties for classes: <description>Class and has<description>Class.
Stimulus controller sample
HTML elements and attributes that invoke and sign Stimulus controller and actions

References:

--

--