Elm is a functional programming language that used to develop frontend applications. Even though you don't use Elm at work, understanding Elm architecture will help you to learn functional reactive programming (FRP) at high level. One of the most popular state management framework - Redux actually inspired from Elm architecture.

Redux evolves the ideas of flux, but avoids its complexity by taking cues from Elm. Dan Abramov, Author of Redux

To understand Elm architecture better, let's try to understand our typical approach for building the frontend applications. Applications are usually divided into three layers

  • Model

  • Controller or View Model

  • View

Model

In frontend applications, this is the common layer where we define the state of our user interface. This is the programmatic representation of the user interface. For example if we have a to-do list, our model might have a list of objects that represent the todo item and may be another boolean to represent the filter that is currently applied. But it doesn't have any business logic.

Controller or View Model

There is where our business logic goes. This layer represents the core business implementation of the application. The model may hold the filter value and the to-do items, but the controller is the one that actually has the logic to filter the to-do items. Usually if something happens in the UI, controller would receive the notification and update the model and UI (if needed).

View

The View has functions to render User Interface components. It decides how to render the Model. For example, if there is a list of to-do items, the View layer decides whether to render it as a list of labels or cards or check boxes.


This approach is been there for long time. It is not just used by web applications, even thick client desktop applications like WPF or Xamarin also uses the same approach. We can see what are the problems with this approach and how Elm architecture solves this problem.

Let's say we have cascade drop downs in UI. We have a Country dropdown and a State dropdown. When selected value gets changed in Country dropdown, the State dropdown list should get updated.

In a typical approach like MVC, the controller will get notified when the selection in country dropdown changed. So the controller will now update the Model with the new selected country value and it also fetch the new list of states based on the selected country and updated the UI.

If you take a closer look, the controller is actually doing two jobs. It is updating the Model as soon as something changed in the UI. Because Model is the representation of UI, so both View and Model has to be in sync. And the controller is also updates the UI, making sure the UI renders the right list of states based on the selected country.

The controller does the heavy job of synchronising the model and view. And the controller gets more complex and complex as the project grows. And also the data is flowing back and forth between the controller and view and that gives very less control over the data. This approach may be suitable for server client applications, but not for single page applications.

How Elm architecture solves the problem

Elm is a pure functional language. So it is all about functions. To understand Elm architecture we need to understand three primary functions.

Init

This function does not take any input parameters but it returns a Model object. The object represents the initial state of the application. This gets called only once over the lifecycle of the component.

View

This function takes Model object as input parameter and returns the DOM object. This function holds the logic, that decides how to render the Model as UI. For example if you have a list of to-do items, this function decides whether to display it as list of labels, cards or text boxes. The DOM object it returns is not just a passive object, it has ability to broadcast messages when something happens in UI.

Update

The Update function accepts two input parameters - a Message and the current State of the application. The message is sent from the DOM object that View function returns. It says what happened in the UI. And the second parameter state holds the current application state. Based on the message this function returns the new state for the application. This function holds the core business logic.

The Update and View functions will get invoked repeatedly, making sure the state and view are always in sync. And the data also flows in single direction, giving you more control over it.

But there is one problem. The View function now becomes a function that computes the User Interface based on the State. And the View get called multiple times, making it returns the whole DOM object every time. But applying the entire DOM to browser is not efficient. So now Virtual DOM comes into picture. Even though the application returns the whole DOM object, only the differences will be identified and applied to the actual DOM.

As I already said even if you don't use Elm at work, understanding Elm architecture will help you to write efficient state management code.