React.js is a phenomenal library, often considered a game-changer in the Python world. However, React only addresses the view layer of a front-end application and lacks built-in solutions for data and state management.
To address this, Facebook, the creators of React, introduced offered some guidance in the form of Flux. Flux, more of an application architecture than a framework, centers around unidirectional data flow using React Views, an Action Dispatcher, and Stores. By adhering to event control principles, Flux simplifies the development, reasoning, and maintenance of React applications.
This article delves into basic Flux control flow examples, highlights the limitations of Stores, and explores how to integrate Backbone Models and Collections seamlessly within a “Flux-compliant” manner.
(Note: For brevity and clarity, the examples are presented in CoffeeScript. Non-CoffeeScript developers can treat them as pseudocode.)
Introduction to Facebook’s Flux
Backbone is a highly regarded library that provides Views, Models, Collections, and Routes, establishing itself as a standard for structured front-end applications. Since React’s debut in 2013, Backbone has often been used alongside it. Most React examples outside of Facebook.com showcase this tandem.
However, relying solely on Backbone for application flow beyond React Views can introduce complexities. In my initial experiences with React-Backbone applications, I quickly encountered the infamous “complex event chains” that I had read about. The intricate web of events, from UI to Models and back, made it challenging to trace data modifications and their origins.
This Flux tutorial will showcase how the Flux pattern addresses these issues with elegance and simplicity.
An Overview
Flux’s core principle is “unidirectional data flow”. The following handy diagram illustrates this flow:

The key takeaway is the unidirectional flow: React --> Dispatcher --> Stores --> React.
Let’s examine the main components and their interactions:
The official documentation provides an important clarification:
Flux is more of a pattern than a framework, and does not have any hard dependencies. However, we often use EventEmitter as a basis for Stores and React for our Views. The one piece of Flux not readily available elsewhere is the Dispatcher. This module is available here to complete your Flux toolbox.
Therefore, Flux comprises three core components:
- Views (
React = require('react')) - Dispatcher (
Dispatcher = require('flux').Dispatcher) - Stores (
EventEmitter = require('events').EventEmitter)- (or, as we’ll soon explore,
Backbone = require('backbone'))
- (or, as we’ll soon explore,
The Views
Given the abundance of resources on React, I’ll refrain from a detailed explanation here, except to say that I find it significantly more intuitive than Angular. Unlike Angular, React rarely leaves me perplexed while coding. However, this is subjective.
The Dispatcher
The Flux Dispatcher serves as a central hub for handling all events that modify Stores. Each Store registers a single callback with the Dispatcher to handle all events. Subsequently, whenever a Store needs modification, an event is dispatched.
Similar to React, the Dispatcher stands out as a well-implemented, sound concept. For instance, consider a to-do list application where users can add items. Here’s how the Dispatcher could be utilized:
| |
| |
| |
This approach simplifies the process of answering two crucial questions:
- Q: What events modify
MyStore?- A: Refer to the
switchstatement cases withinMyStore.dispatchCallback.
- A: Refer to the
- Q: What are the potential sources of that event?
- A: Simply search for the specific
actionType.
- A: Simply search for the specific
This method is far more efficient than, for example, searching for MyModel.set, MyModel.save, MyCollection.add, and so on, which can quickly become unwieldy.
The Dispatcher also enables sequential execution of callbacks synchronously using waitFor. For instance:
| |
I was genuinely surprised by the significant improvement in code cleanliness achieved by using the Dispatcher for Store modifications, even without leveraging waitFor.
The Stores
While we understand that data flows into Stores via the Dispatcher, how does it reach the Views (i.e., React)? As stated in the Flux docs:
[The] view listens for events that are broadcast by the stores that it depends on.
Essentially, we register callbacks with our Views (React Components), similar to how we did with Stores. We instruct React to re-render whenever a change occurs in the Store passed through its props.
Here’s an example:
| |
Excellent!
Now, how do we emit the "change" event? Flux recommends utilizing EventEmitter. Let’s consider an official example:
| |
This feels cumbersome! Do we have to write all this boilerplate code every time we need a simple Store, which is seemingly required for every piece of information we want to display? There must be a better way!
The Missing Piece
Backbone’s Models and Collections already encompass the functionality provided by Flux’s EventEmitter-based Stores.
By recommending raw EventEmitter, Flux essentially suggests recreating a significant portion of Backbone’s Models & Collections for every Store. This is akin to using bare Node.js for server-side development when mature microframeworks like Express.js already exist to handle the basics.
Just as Express.js builds upon Node.js, Backbone’s Models and Collections utilize EventEmitter as their foundation. They offer all the essential features, including change event emission, query methods, getters, setters, and more. Furthermore, Backbone’s Jeremy Ashkenas and his team of 230 contributors have undoubtedly implemented these functionalities more robustly than most of us could.
To illustrate, I’ve converted the MessageStore example above to utilize a Backbone version:
The code is objectively shorter (no redundant code) and subjectively clearer and more concise (e.g., this.add(message) instead of _messages[message.id] = message).
Therefore, let’s leverage Backbone for our Stores!
The FluxBone Pattern: Flux Stores by Backbone
This approach forms the basis of what I call FluxBone, a Flux architecture that employs Backbone for Stores. Here’s the fundamental pattern:
- Stores are instantiated as Backbone Models or Collections that have registered a callback with the Dispatcher, typically as singletons.
- View components never directly modify Stores (e.g., no
.set()calls). Instead, they dispatch Actions to the Dispatcher. - View components query Stores and bind to their events to trigger updates.

Let’s break down each step with Backbone and Flux examples:
1. Stores are instantiated as Backbone Models or Collections, registered with the Dispatcher.
| |
| |
2. Components dispatch Actions, not direct Store modifications.
| |
3. Components query Stores, bind to events for updates.
| |
Having implemented this Flux-Backbone approach in my projects, I witnessed a remarkable transformation after refactoring my React application. The code sections that previously caused frustration were replaced by a logical and streamlined flow. The seamless integration of Backbone into this pattern is truly impressive, eliminating any friction between Backbone, Flux, and React.
Example Mixin
Repeatedly writing this.on(...) and this.off(...) for every FluxBone Store added to a component can become tedious.
Here’s a simple React Mixin that can streamline this process:
| |
| |
Syncing with a Web API
The original Flux diagram depicts interactions with the Web API solely through ActionCreators, requiring a server response before dispatching actions. However, shouldn’t the Store be the first to know about changes, even before the server?
I propose reversing this flow: Stores interact directly with a RESTful CRUD API using Backbone’s sync() method. This proves highly convenient, especially when working with a true RESTful CRUD API.
Data integrity remains intact. When .set() is called with a new property, the change event triggers a React re-render, optimistically displaying the new data. During .save() to the server, the request event prompts a loading indicator. Upon successful completion, the sync event removes the indicator, while the error event highlights issues. You can find inspiration here.
Furthermore, Backbone provides validation (and an invalid event) as a first line of defense and a .fetch() method to retrieve updated information from the server.
For non-standard tasks, interacting via ActionCreators might be more suitable. It’s plausible that Facebook doesn’t rely heavily on “mere CRUD,” explaining their preference for not prioritizing Stores.
Conclusion
Facebook’s Engineering teams have made significant contributions to advancing front-end development with React. Flux provides a glimpse into a scalable architecture, both technologically and from an engineering perspective. By cleverly integrating Backbone, as demonstrated in this tutorial, Flux’s capabilities can be enhanced, empowering developers and teams of all sizes to build and maintain impressive applications.