How The Elm Architecture Works

Introduction

Let’s take a look at the counter app.

module Main exposing (main)

import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)

main : Program () Model Msg
main =
  Browser.sandbox
    { init = init
    , view = view
    , update = update
    }

type alias Model = Int

init : Model
init = 0

view : Model -> Html Msg
view n =
  div []
    [ button [ onClick Decrement ] [ text "-" ]
    , text (String.fromInt n)
    , button [ onClick Increment ] [ text "+" ]
    ]

type Msg
  = Decrement
  | Increment

update : Msg -> Model -> Model
update msg n =
  case msg of
    Decrement ->
      n - 1

    Increment ->
      n + 1

How does it work?

Specifically, when I click one of the buttons how does Elm know to increment or decrement the number and then update the display?

At the start

Browser.sandbox initializes the Elm runtime. It tells the runtime:

  1. The initial state for our app.
  2. The view function to use to render our state as HTML.
  3. And, the update function to use when it’s time to update our state.

When the app loads for the first time the HTML is rendered by passing the initial state to the view function. That’s why you see the following:

The counter at 0

When a button is clicked

So the app has been running for a while and we now decide to click the “+” button. Here’s roughly what happens:

  1. A click event is generated by the DOM.
  2. The event is translated into our Msg type of the value Increment.
  3. The update function is called with the values msg = Increment and n = 0. The Increment case is taken and so the update function returns n + 1 = 0 + 1 = 1.
  4. The runtime changes our state to be the return value of the update function. So our state is now 1.
  5. Finally, since the state has changed, the runtime calls the view function with the new state in order to render the HTML for our app. That’s why we now see a 1 instead of a 0.

The counter after clicking the "+" button

Test your understanding

Convince yourself that you understand how the app works by explaining what happens when you click the “-“ button.

Further reading