I’ve recently implemented flux into my React Meteor workflow. It’s really helped improve debugging and maintainability. I’ve used this on parts of a production app with complex state and it has been working well!
I suspect this will not be as well received by current Meteor devs but I think that current React devs will find this natural and will see how nice Meteor can work to make their Flux reactive with an optimistic UI (writing a blog post for that).
The gist with flux is your UI triggers ‘actions’. A dispatcher catches these actions and sends the payload to anyone listening (a data store or component). The stores manipulate their state based on the action. Components listen to stores and sync their data when a ‘store changed’ event is heard. That’s it!
The key is to have Tracker watch a collection and trigger an action when it changes. The store(s) can listen for this change and re-sync (which trigger changes in the UI).
At first it may seem like using flux with Meteor is going to cause a lot of overlap and extra work. However there isn’t much overlap. It also eliminates the ReactiveDataMixin plugin and allows you to have more control over re-renders.
Tracker.autorun(computation => {
var docs = Players.find({}).fetch();
if (computation.firstRun) return; // ignore first empty run
console.log('[Tracker] collection changed');
this.CollectionActions.playersChanged(docs);
});
This can be reduced down to a helper function. Pass in the collection to watch and a callback function to call when it changes.
watchForCollectionChanges(Players, Actions.playersChanged);
The data lifecycle looks like this:
- render PlayerList component and listen to PlayerStore (empty array at this point)
- subscribe to players subscription
- tracker fires ‘collection changed’ event
- dispatcher send event to stores listening
- PlayerStore fetches Minimongo to refresh store, emit store changed
- dispatcher sends event to listeners
- PlayerList acts on ‘store changed’ event and fetches store state, passes to children,
- UI gets updated with new data from parent (PlayerList)
All the data coming from flux and going to the components is non-reactive. However, because tracker updates the stores, all of the latency compensation and realtime updates still work like normal!
This repo shows how you can use Alt, a flavor of flux, with the leaderboard app. Note, the dispatcher is fired when an action returns, this reduces the boilerplate and complexity of vanilla flux (I may add a branch with that too if there’s enough interest).

