The Redux Pattern As a First-Class Citizen

(A Redux Developer’s Guide to Elm Basics)

Why Look at Elm?

Unlike Redux, Elm is a language, so it is able to benefit from many things like enforced purity, static typing, out of the box immutability, and pattern matching (using the case expression). Even if you don’t plan to use Elm, you should read about the Elm architecture, and play with it.
— From the Official Redux Guide Prior Art section

If You Know Redux, You Know The Elm Architecture!

The Elm Architecture and Redux pattern side-by-side. Since Redux was inspired by The Elm Architecture, they are exactly the same!

The words in parens are the Redux equivalents of the Elm concept they are next to. This article describes these differences in more detail and compares the equivalent code in both.

If They’re The Same, Why Consider Elm?

There have been a lot of articles recently about moving away from Redux. The consensus seems to be that the Redux Pattern can make code more maintainable and reduce data synchronization bugs, but the cost is too high because it requires so much boilerplate. So many people are recommending using the same patterns without the Redux library itself (including Dan Abramov, the original author of Redux; see this post as well).

But there’s another option! With Elm, the patterns of Redux are built into the language itself (not an optional library or framework). That means that it’s a lot more natural because the language is literally built for creating apps using that pattern. It also means no “JavaScript Fatigue” because Elm is opinionated about its data store. So no updating to the flavor-of-the-month data store (and a custom set of supporting libraries). Plus, you have to deal with a lot less boilerplate, and you have the famously helpful Elm compiler helping you avoid bugs!

Comparing Elm and Redux

This guide is meant to bridge the gap and help you learn Elm by leveraging the knowledge you already have about Redux. We’ll compare basic Counter apps in both paradigms. This isn’t meant to be a comprehensive comparison, but rather a basic intro to the fundamentals.

Here are the full code examples used throughout this guide:

Live Example in Redux
🌳 Live Example in Elm

(The Redux example is in a single file for easy comparison; see this codesandbox for the same example split into multiple files).

Initializing and Updating State

Redux Reducers, 🌳 Elm update and init functions

Redux Reducer

🌳 Elm update/init functions

Notice that we have to have a default case in Redux. Since action.type is just a string it could be anything. Often tools like TypeScript or Flow are used to help make sure we are handling each valid case and don’t have any typos or incorrect assumptions about the Redux event payloads.

Using just Vanilla Elm, the compiler gives you these guarantees. And there are no escape hatches like TypeScript’s any type, so if your program runs you are guaranteed that there will be no unhandled cases or runtime exceptions.

Triggering Events

Redux Actions, 🌳 Elm Messages (Msg)

Redux Actions

🌳 Elm Messages (Msg)

Notice that in Elm, there is no wiring to manually dispatch actions as there is in Redux. In React, onClick takes a function, so you manually wire it up to call store.dispatch(...) in the function you pass to onClick. Elm assumes an architecture where you the only thing you can do from an onClick (or any other event) is dispatch an action (or Msg in Elm lingo). So this is simpler and less error prone in Elm. You just declaratively give an onClick Increment and The Elm Architecture takes care of the wiring to dispatch the Increment Msg at the appropriate time. This is one of the big benefits of having the data architecture built into the language. It’s also type-safe, which you’ll appreciate a lot more when you’re working with a large scale app and not just a toy example like this! That guarantees that every Msg has exactly the data you said it would, and that you have handled every possible Msg (and only possible Msgs).

Also notice that there is no need for anything like PropTypes in Elm to give you warnings when you forget to pass fields or pass in the wrong data type. This is built with Elm’s famously helpful compiler and type system!

HTML Templating

Redux JSX, 🌳 Elm Functions from the Html Module

That’s right, Elm doesn’t have JSX or a special templating syntax. It’s just plain-old Elm functions! This is one of those features that bothers people when they first use Elm, and then they fall in love with it after a few weeks! And as for the commas at the start of each line, you’ll get used to that, too. Especially because you don’t have to do it manually, elm-format does it for you whenever you save your code!

Tooling

Built-In to Elm

People blame Redux, React, functional programming, immutability, and many other things for their woes, and I understand them.

— Dan Abramov (author of Redux), from You Might Not Need Redux

Indeed, introducing tools for immutability, or ensuring pure reducers is tedious in a React application. But these things aren’t inherently tedious. They are tedious because they are second-class citizens in JavaScript/React. In Elm, however, they are built-in and therefore require no special libraries, no linters or unit tests to ensure that you have pure functions. That’s just how Elm is, and it is very natural to work that way in that context.

Have questions? Drop me a line, or sign up for my Elm for Redux Devs series!

Want to learn my 3 favorite things about Elm? Sign up for my Elm For Redux Devs mini-course below. You’ll get an email in your inbox that gives you some resources about libraries and features of the Elm language to look forward to!

Trying Elm

Is your team curious about Elm? I train teams on Elm, and coach them through the transition from Redux to Elm to make sure it is smooth and successful. Say hello, or take a look at the free Elm intro sessions that we offer.

Thanks For Reading!

  • What have been your stumbling blocks learning Elm?
  • What do you love about what you’ve seen in Elm?

👇 Let me know in the comments below 👇

Did you know? 💡 If you learned something from this guide, you can give up to 50 claps! 👏