Elm:
Using a debugger

How to:

Elm doesn’t have a built-in debugger in the traditional sense that, say, JavaScript does with browser dev tools. However, the Elm community has built tools to fill this gap. Here’s how you can use elm-debug-transformer to debug your Elm app:

-- Install elm-debug-transformer (Node package)

1. npm install -g elm-debug-transformer

-- Use elm-debug-transformer to start your app

2. elm-debug-transformer --port=8000 yourMainElmFile.elm 

Once elm-debug-transformer is running, it creates a WebSocket connection for logging. You’ll see debug information in your browser’s console where you can inspect your program’s data structures at given points in your application.

In Elm 0.19 and later, the Debug module’s functions like Debug.log and Debug.todo can help you trace values and deliberately mark unfinished parts of your code. Here’s how to use Debug.log:

import Debug

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        Increment ->
            ( Debug.log "Incrementing" { model | count = model.count + 1 }, Cmd.none )

        Decrement ->
            ( Debug.log "Decrementing" { model | count = model.count - 1 }, Cmd.none )

You’ll see “Incrementing” or “Decrementing” messages in your browser’s console along with the new state of the model.

Deep Dive

Elm’s author, Evan Czaplicki, aimed to make a language where common bugs would be impossible or easy to catch. This philosophy is why Elm’s core doesn’t include traditional debugging functions. Elm’s static analysis and type inference contribute massively to reducing runtime errors, which decreases the need for sophisticated runtime debugging. Historical alternatives included using the now deprecated elm-reactor which offered time-travel debugging—a way to rewind and replay actions in your app.

Today, tools like elm-debug-transformer and the use of Elm’s Debug module help bridge the gap. While the Debug module is intended for use during development only and should be removed before production builds, it’s an invaluable tool for pinpointing and logging state changes.

Keep in mind that traditional JavaScript debugging techniques, like breakpoints or step-by-step execution, aren’t directly applicable in Elm due to its architecture and the Elm runtime handling state updates. Elm encourages you to structure your program such that data flow is clear and follows strict types and immutability guarantees, minimizing the cases where debugging is needed.

See Also