In order to eliminate unwanted roadblocks in the future, a framework must be flexible. It must also be simple and easy to use. Developers want to focus their time and attention on developing rather than tackling the learning curve to get a new framework up and running. ArkhamJS is just that, flexible and simple. There are is no one way to use the framework. It easily conforms to your app and development style.

Using the Flux architecture as a foundation and Redux as an inspiration, we have evolved ArkhamJS into a sleek new framework, targeted for those who are starting a new project or refactoring their own custom Flux framework.


  • Single store. A single store makes it easy to retrieve all your data from one location.


You can install the ArkhamJS module via NPM with the following command:

npm install --save arkhamjs

The full source code can be found on GitHub. It consists of two classes, Flux and Store. Store is a base to extend your stores from. Flux is what makes everything tick. It handles your events and manages the state of your stores.


Actions are objects containing a type property and optional data objects to update. A basic action will simply emit an event with the type. Events are simply a unique string.

// Basic action
{type: 'USER_UPDATE'}

If you would like to send data along with your action, just add them to the object.

// Session objects
const session = Immutable.fromJS({
name: 'Bruce Wayne',
token: 'dark_knight'
const isLoggedIn = true;
// Action with objects
{type: 'USER_UPDATE', session, isLoggedIn}

Each action is dispatched through the Flux.dispatch method.

Flux.dispatch({type: 'USER_UPDATE', session});

A dispatch can also be called without emitting an event, just updating the store, by setting the second parameter, silent, to true:

Flux.dispatch({type: 'USER_UPDATE', session}, true);

The use of actions can vary from hitting API endpoints to just emitting a basic event. An action file would look something like:

import {Flux} from 'arkhamjs';
import {UserService} from 'services';
import Immutable from 'immutable';
export default UserActions = {
ping: () => {
// An example of emitting the event, USER_PING
Flux.dispatch({type: 'USER_PING'});

update: () => {
// An example where an API call returns a promise with a result
const token = Flux.getStore(['user', 'session', 'token']);

if(!token) {
// Only get new token if one doesn't already exist
return UserService.updateUser()
.then(results => {
const session = Immutable.fromJS(results));
return Flux.dispatch({type: UPDATE_USER, session});


ArkhamJS uses a single store, similar to Redux but with a hierarchy of all the stores within. This way the data is not scattered about and easy to cache.

Each store has two important methods, initialState and onAction. When a store is registered, it first tries to check for any cached data in sessionStorage, if none exists, it then populates that store property with the initial data.

The initialState method declares the initial values of the properties within the store. The initial values can be booleans, strings, numbers, or JSON objects and arrays. This way you can add a few default values.

initialState() {
return {
session: {}

Next we let the store know how we would like to alter the data when a specific event comes through. In this example we see the user object has been converted to an ImmutableJS object. It is overwritten by a new user object obtained by our action.

The onAction method takes three params. The type, or event that is called. Data is a Map (immutable object) of any objects sent along with the action. And last is the state. This is the last saved state for the current store.

onAction(type, data, state) {
switch(type) {
return state.set('session', data.get('session'));

By default, if an event is action is dispatched without any triggers in the stores, it will still emit an event with the type. The last state is returned by default. Otherwise the store would catch the type in a switch statement and alter the state, returning the new state.

There are a few ways you can access the current state in the store. All data is obtained through the Flux.getStore() method. It can be executed with no parameters to return the parent store. This will return all store values in your app. Or you can pass a string with the name of a particular store you would like access to. Or you can pass an array with the path of the specific value you want (similar to the getIn in ImmutableJS).

// returns {user: {session: {name: 'Bruce Wayne'}}}
// returns {session: {name: 'Bruce Wayne'}}
Flux.getStore(['user', 'session']);
// returns {name: 'Bruce Wayne'}


Any view and/or component that requires an update when the data has changed will require a listener. Methods called on the event can grab the data from the single store and return the values needed.

Your root view, or initial view, will require you to register each store. This is accomplished with the Flux.registerStore() method.

The class of the store is passed as a param to the registerStore method to register a single store. If multiple stores are to be registered, an array of classes can be passed.

// Single store registration
// Multiple store registration
Flux.registerStore([AppStore, UserStore]);

By default all types in an action will be emitted as events when dispatched by the Flux.dispatch() method. The recommended Flux architecture would be to listen in on an event and call a method:

import React, {Component} from 'react';
import {Flux} from 'arkhamjs';
import {Map} from 'immutable';
import {UserStore} from 'stores';
export default class SessionView extends Component {
constructor() {
// Make sure your methods are bound correctly
this.onUpdateUser = this.onUpdateUser.bind(this);

// Register stores. We should only do this once in the root view
// Initial session
this.state = {
session: Map()
componentWillMount() {
// Add a listener before the component mounts
Flux.on('USER_UPDATE', this.onUpdateUser);
// Call on the action method to update user
componentWillUnmount() {
// Remove listener when component unmounts'USER_UPDATE', this.onUpdateUser);
onUpdateUser() {
// Get the session object from the store. It has been updated
// before the event was emitted.
const session = Flux.getStore(['user', 'session']);

// Update the state and trigger a re-render
render() {
return <div>{this.state.session.get('name')}</div>;

You can also get the data that is sent with the event. This would be before any mutations by the store. Just the raw data coming from the actions.

onUpdateUser(data) {
// Get the session object from the action.
const session = data.get('session');

// Update the state and trigger a re-render

The following way is not recommended but can come in handy under certain situations. each dispatch returns an array of data. An array of results for each action dispatched.

UserActions.update.then(actions => {
// Let's get the first action, UPDATE_USER
const a = actions[0];
// Get the session
const session = a.get('session');
// Update state


The most important part of development is debugging. We have included an advanced debugger to spit out your actions and states. Once your debugger is enabled, every time an action is dispatched, it will be displayed in your console log. It will indicate whether or not your state has changed and allow you to view your store’s values.

ArkhamJS is an exciting new twist to the world of JavaScript frameworks. Bringing back the fun in development. Focusing our efforts on creating beautifully sophisticated apps for our users to enjoy.

A full skeleton app can be found on GitHub. If there are any questions, recommendations, or concerns, please email or check out our Gitter. Thanks for your interest!