Providence: Better State Management for React and MFEs

Hello all!

A while back I was working heavily on MFEs and we were using Redux to handle state management. It’s my understanding that the requirement to use Redux has been dropped. That makes sense, given that Redux is incredibly verbose and frustrating to work with.

However, leaving Redux means leaving its ecosystem, feature benefits, and guarantees. There has not been a good tool to tame this beast-- until now. I’ve written up a blog post on OpenCraft’s new library for better state management for React named Providence. It’s unique in that it uses Redux as a storage driver while presenting a far more developer-friendly interface for handling 90%+ of the use cases you need Redux for.

Some of you might have attended my workshop at the conference on building your own Micro Front End. If you didn’t, you should know that over half of the presentation was just wrangling Redux. By the end, we retrofitted the MFE in a few minutes with Providence and removed four entire files worth of boilerplate, all while making the intent and meaning of the code much clearer. Here is an MR that demonstrates how an example MFE can be converted over to use Providence.

We are using Providence internally to build Listaflow (the new Open Source recurring workflow app being used by the Core Contributors for their checkins) and other tools using React on the frontend. We’d love to see more teams using it and contributing to it as a useful tool. Please let me know what you think of it and if there are any questions you have. You can read the full documentation here, and you can check out a very basic live demo of the functionality here. I recommend reading the source code alongside playing with it.

8 Likes

From a technology radar perspective, redux is a technology we’ve “accepted” - a tech that we have serious experience with and that we’ve had success using to solve problems. (Deets on what this status means here: https://openedx.atlassian.net/wiki/spaces/AC/pages/2844786770/Open+edX+Technology+Radar)

The maintainers of Redux have invested a great deal of time and effort into Redux Toolkit, which solves many of the industry’s complaints around Redux’s verbosity and level of boilerplate. I’d strongly suggest we first look to Redux Toolkit before we roll our own state management solutions. The ecosystem around and ubiquity of the library shouldn’t be underestimated.

Many of our very early MFEs use Redux without Redux Toolkit and I’ll agree, they’re a pain in the ass. Worse, they use redux-saga for many use cases where redux-thunk (or not using redux/thunks at all!) would serve just fine. I’d love to see us invest in modernizing and simplifying them to use current best practices (like Redux Toolkit), but have never been able to prioritize making it happen.

I’m quite familiar with Redux Toolkit, and in fact use it quite extensively in this tutorial on building your own MFE I wrote some time ago. During the Open edX conference, I had my two hour workshop running through all the components needed to set up a very basic MFE that just did the work of displaying a course catalog. Almost all of the time spent was on making Redux work, even with the benefits of Redux Toolkit.

Then, in the last five to ten minutes or so, I had the learners rewrite the MFE’s state management using Providence instead. It eliminated several files of work from the project and replaced them with only a few lines.

This is because Providence works on a higher abstraction layer than Redux and Redux Toolkit do. In fact, Providence uses Redux Toolkit to build out the stores and automations it makes.

To do this, it does make some assumptions about use cases and the data. However these assumptions do fit 90+% of the use cases we use Redux for, and for those it does not cover, Providence works seamlessly alongside traditionally built Redux stores without getting in the way. It can be easily added to existing MFEs without breaking existing stores.

The article you link is describing an event that happened in the past to have technologies accepted. At the time this article was created, Providence did not yet exist. What work does Providence need to go through to get to accepted status?

The spirit behind the tech radar is roughly: things we’re trialing are “provisional”, things that have been proved successful in many use cases but aren’t ubiquitous are “accepted”, and things that are widely adopted and successful are “adopted”. “Hold” means tech we actively want to stop using.

So the idea would be to use it! If OpenCraft loves the tool and thinks it should be used more widely, maybe we add it as Provisional soon to raise its profile a bit. I think it’s a bit nebulous whether things on the tech radar are all used in the ‘core’ of Open edX or whether they’re also used in custom apps which aren’t technically part of the platform, but are part of our community/ecosystem. Curious what others think on that.

So finding an MFE to use it in, talking more about its utility and why we’d want to use it over other tools, etc., and having the conversation, is probably the right path forward.

1 Like

Great! @arbrandes You were there for the MFE workshop-- just wanted to call your attention to this thread if you haven’t seen it yet :slight_smile:

The main reason to use Providence is that it lets you leverage Redux’s capabilities while providing a lot of the minutia you’d otherwise have to add in over and over again, like state management surrounding the fetching of resources (both single modules and arrays from a paginated endpoint), debounced PATCH requests when editing a field on a model, and form creation/validation/submission.

For example:

const controller = useSingle('product', {endpoint: 'https://example.com/api/products/x/'})

What does this line get you?

  • A Redux Module with mutations
  • A controller that makes the state easy to update
  • Easy REST patching
  • Error handling for fetching and updating the object

This is the sort of thing it used to take many files of repetitive code to accomplish, even with Redux Toolkit. And the hooks are smart enough to descope the module and remove it from the store the moment it’s no longer needed. This also greatly reduces the size of an MFE and the amount of code that would have to be reviewed, since the slices are dynamically generated by the library. And best of all, it’s TypeScript enabled. This might not be a fully leveraged advantage right now since the MFEs are written in JS, but even just having the library written in TypeScript makes a developer’s IDE able to make sensible predictions and detect errors early.

It allows the writers of an MFE to focus on the UX and the business logic of what they’re doing, since almost all of the API request handling and state management code will be autogenerated.

Anyway, those are some of the main reasons to use it over other solutions-- as far as I know, nothing is available that works on this level of abstraction and automation on top of Redux. There are libraries that do some of this work, but usually with a far more verbose invocation even within their smaller scope.

I’ll work with the team internally to see about showcasing some of its use within a current MFE project, though as you noted, it is used in Listaflow, which might not qualify it for the radar yet, but at least shows its utility. :slight_smile: