Functional Reactive UI Programming

DZone 's Guide to

Functional Reactive UI Programming

This article gives a brief introduction to a new way of building UIs and lists the main advantages it has over traditional approaches.

· Web Dev Zone ·
Free Resource

This article is featured in the new DZone Guide to Web Development: Applications and Frameworks, Volume I. Get your free copy for more insightful articles, industry statistics, and more!

Frontend Development Beyond the MVC Pattern

React.js, Elm, Cycle.js, and other UI frameworks introduced a new way of building user interfaces. By applying principles from functional reactive programming to UI development, they even changed how we think about user interfaces. This article gives a brief introduction into this new way of building UIs and lists the main advantages it has over traditional approaches.

Image title

The picture above shows a rough overview of the concepts, which are shared between pretty much all modern UI frameworks that foster reactive programming. The first thing to note is that everything—all changes, events, and updates—flow in a single direction to form a cycle.

Functional Reactive UI Development

The cycle consists of four data structures (State, Virtual DOM, Event, and Action) and four components (View()-Function, DOM-Driver, ActionCreator, and Updater). The DOM-Driver is provided by the framework, while the other components have to be implemented by the application developer.

Let’s assume our application, a todo list, has already been running for a while and the user presses a button to create a new entry in the todo list. This will result in a button-clicked event in the DOM, which is captured by the DOM-Driver and forwarded to one of our ActionCreators.

The ActionCreator takes the DOM-event and maps it to an action. Actions are an implementation of the Command Pattern, i.e. they describe what should be done, but do not modify anything themselves. In our example, we create an AddToDoItemAction and pass it to the Updater.

The Updater contains the application logic. It keeps a reference to the current state of the application. Every time it receives an action from one of the ActionCreators, it generates the new state. In our example, if the current state contains three todo items and we receive the AddToDoItemAction, the Updater will create a new state that contains the existing todo items plus a new one.

The state is passed to the View()-Function, which creates the so-called Virtual DOM. As the name suggests, the Virtual DOM is not the real DOM, but it is a data-structure that describes how the DOM should look like. The code snippet on the top left of the next page shows an example
of a Virtual DOM for a simple<div>.

{ tagName: ‘div’,
    attributes: {
        class: ‘view’
    children: [
        { tagName: ‘input’, ... },
        { tagName: ‘label’, ... },
        { tagName: ‘button’, ... }

The Virtual DOM is passed to the DOM-Driver which will update the DOM and wait for the next user input. With this, the cycle ends.


Functional reactive UI development has three major advantages over traditional approaches, all of which are huge: straightforward testing, a comprehensive flow of events, and time travel (yes, seriously).

Straightforward Testing

The View()-Function and the ActionCreators are simple mappings, while the Updater performs a fold (also often called a reduce) on the Actions it receives. All components are pure functions and pure functions are extremely easy to test.

The outcome of a pure function depends only on the input parameters and they do not have any side effects. To test a pure function, it is sufficient to create the input parameter, run the “function under test” and compare the outcome. No mockups, no dependency injection, and no complex setup are necessary.

Comprehensive Flow of Events

The control flow of graphical user interfaces is inherently event-based. An application has to react to button-clicks, keyboard input, and other events from users or servers. Applying reactive techniques, be it the Observer Pattern, data-bindings, or reactive streams, comes naturally.

Unfortunately, these techniques come with a price. If a component A calls a component B, it is simple to see the connection in your IDE or debugger. But if both components are connected via events, the relationship is not as obvious. The larger the application becomes, the harder it gets to understand its internals.

The architecture of a functional reactive application avoids these problems by defining a simple flow of events that all components must follow.

No matter how large your application grows, the flow of events will never change.

Time Travel

Functional reactive applications allow you to travel back and forth in time. If we store the initial state and all actions, we can use a technique called “Event Sourcing.” By replaying the actions, we can recalculate every state the application was in. If we replay only the last n-1, n-2, n-3... actions, we can actually step back in time. And by modifying the recorded stream of actions while applying them, we can even change the past. As you can imagine this can be very handy during development and bugfixing.

The first time-traveling debuggers have been built, but I think we have only started to understand the possibilities, and more amazing tools will be released in the future.


So far we have only scratched the surface of functional reactive UI development, but by now it should be clear that this approach has tremendous advantages. Most people, who have made the switch to functional reactive UI programming, never want to go back.

More Web Dev Goodness:

For more insights on working with the latest frameworks using third-party APIs, implementing module JavaScript for clean and reusable code, and more, get your free copy of the new DZone Guide to Web Development!

If you'd like to see other articles in this guide, be sure to check out:

web dev ,functional reactive ui development ,user interface

Published at DZone with permission of Michael Heinrichs , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}