Why is it better to preserve state in the DOM?

This goes beyond my expertise and would love to have the community feedback on this question.

Up to know I have mostly followed the stimulus way to store state in the dom as describe in the handbook.

looking back at the slideshow example, I rewrote it without using DOM state but using an instance variable of the controller class as the index.
The Remix can be seen here https://glitch.com/edit/#!/charm-talk?path=src/controllers/slideshow_controller.js:1:100:

and the controller code :

import { Controller } from "stimulus"

export default class extends Controller {
  static targets = [ "slide" ]

  connect() {
    this.index = 0;

  next() {

  previous() {

  showCurrentSlide() {
    this.slideTargets.forEach((el, i) => {
      el.classList.toggle("slide--current", this.index == i)

For this particular example, it is working fine but I am sure I am missing something.
I read several times the handbook section about Dom state but just can figure out clearly what is the advantage of storing the state in the DOM vs in the controller instance?

One advantage I see is the ability to pass some initial state to the controller dynamically generated by erb.

thanks for your feedback

1 Like

As a Rails developer nearly all my html is generated server side. In fact on a new project I’m trying to do everything serverside and forego the whole clientside template rendering that has sucked me in over the years. By having this view state in the DOM it becomes very easy to pass values from the server without needing to make additional requests.


The advantage of keeping state in DOM (HTML data properties) becomes obvious when using stimulus in combination with turbolinks. If state is kept in DOM, then when a page with stimulus controller is cached by turbolinks, controller state gets automatically saved as well and controller can be fully recovered from cache.

Using your example above, if state is saved in DOM, active slide is cached, as it’s saved as “data” attribute in HTML and when retrieving cached version, controller will be able to load the last active slide. If using “instance variables”, the state would be lost when cached and controller would display first slide when page is pulled from cache.

If you are not planing on, or using turbolinks, then it doesn’t really matter how you store state. You can also mix and match, using DOM for state that matters on initialization and instance variables for any intermediary state.


Thanks @sect2k this makes a lot of sense, I knew it was something like this but couldn’t narrow it as clearly as you did.
Turbolinks cache and passing initial states from the sever to the controller makes 2 strong benefits of using stimulus DOM state