Announcing new and simple state manager “Exome”
Tags: javascript, react, webdev, typescript
Published: 2021-04-17 09:12:56

**TLDR**: I created new state library called [Exome](https://github.com/Marcisbee/exome) (works with React and there's a PR for Vue too (excuse me, that sounded like a pokemon)). The end.

# Introduction
Let me introduce myself first. I'm working as a front-end dev for as long as I can remember. Since before the days of jQuery dominance even. So I've seen a lot from dead simple JS libraries to utterly complex ones and again back to simple ones and so on. When I started learning Redux, NgRx and Vuex back in a day it was a high hill to climb at first always wishing for something easier. Much easier, like a plain object being state easier.

So I started tinkering with different ideas of how I would like my ideal state manager to look and feel years ago. I remember having random ideas at random times and just dropped them in notes. I never did anything with those because none of them really felt good enough.

Until now when I reached a point when starting new project where working with deeply nested tree structures was a must have. Since that is one of Redux (and I'd say the whole flux architecture for that matter) core problems, I went with [valtio](https://github.com/pmndrs/valtio), a library by Pmndrs. And it was great at first, but then I started to see a real mess in code with my made up actions and selectors making sense less and less. And line between what gets selected from state and what updated became blurred together. So I knew that I had only one option, to finally figure out my dream state manager.

# From idea to library
I set a few goals for state manager I wanted:

1. Must have actions (in a sense that it would be the only way to modify state);
2. Must integrate with Redux Devtools and to see deeply nested objects right away, not clicking through tree to find exact one I'm looking for;
3. Must be typed via TypeScript, I mean when working with data, there must be some guards and of course that sweet autocomplete;
4. Must be able to save and load as a string (since in my case I needed a way to save state in a file and restore it);
5. Must be dead simple so any junior developer can get productive right away;
6. Must not bottleneck the view renderer (must be performant).

So those were my initial goals and in a single evening I came up with [Exome](https://github.com/Marcisbee/exome) and developed a prototype. I was so happy with it that I decided to make it open source. It really hits all of the goals I set and more. ~~Only issue is that [it doesn't support IE11](https://caniuse.com/proxy), since it uses Proxy. But in my case it didn't matter.~~ Not true anymore! It [support IE11](https://github.com/Marcisbee/exome#ie-support) too.

# Examples
So to start off here's a primitive counter example (click on number to increment it).

{% codesandbox exome-counter-96qfq %}

And that's it, no providers, no contexts, no boilerplate. Store is just a class. Properties are state values and methods are actions. Whenever action is called, state is updated and wired view components (via `useStore`) are rendered. It updates only those components that uses particular Exome instance in `useStore` hook. It's simple as that.

Ok everyone can do a counter example. What about that deeply nested tree part that was in my goals. Aah great question. So I threw up a simple router example for this.

{% codesandbox exome-routes-w2yq4 %}

This is more complex one. I wanted to demonstrate here that we can have Store that can have multiple Tabs and those Tabs can also have multiple Items. So it's a nested tree. Just pass child Exome instance through `useStore` and that child component will be wired.

# Devtools

Working with Redux Devtools to examine Exome state is a breeze too. No need to dig deep into state tree to find Exome you're looking for. But if you want to see whole tree, that's available too (all Exome childs are examinable in full tree view).

![Exome state explored in Redux Devtools](https://miro.medium.com/max/1400/1*CkoYissBpbKxGmiMwYb-eg.png)

_Note: Since devtools have [weird bugs](https://github.com/zalmoxisus/redux-devtools-extension/issues/737) when using `serializedType` every Exome will have `$$exome_id` until those bugs are resolved._

Saving and loading state is described in details in API docs (https://github.com/Marcisbee/exome#savestate).

# Performance
It's great! And will be more and more optimised as library matures.

To get the feel of how this library performs, I created a [benchmarks](https://github.com/Marcisbee/exome/tree/main/benchmark#benchmarks) (really, really primitive ones). And the results are quite good, in fact Exome seems to be the fastest library out of what I've tested (at least on my machine — Macbook Pro 2020 M1). And here are the results:

![Render component benchmarks](https://miro.medium.com/max/1008/1*e-Dyk7YEyiNuZwVFMo0wPg.png)

It's a simple counter example in React, that gets rendered in first benchmark. And in second one count gets incremented and rendered via view update.

![Increment action benchmarks](https://miro.medium.com/max/1008/1*bCKOoKVCAnuYfBOZqA7R0w.png)

Please note that these benchmarks are not intended to make any library look bad (in fact they all are really great). Main intention is to see where Exome stands in terms of Performance and where and how to improve it. And I know those are very primitive benchmarks, but I don't really want to spend a lot of my time to create real world apps for each store. Maybe in future.

# Conclusion

There are more perks to Exome that we didn't explore, but most of them are explained in [readme](https://github.com/Marcisbee/exome#readme).

The most exciting one is that micro-frontends can share single state between them. I created a [tiny example](https://codesandbox.io/s/vue-exome-lchcp?file=/src/App.vue) where I created single Exome store and passed it to React and Vue. Whenever something changes in state, it gets synced across all frameworks that utilise Exome middleware. It just works.

![Vue counter and React counter sharing counter state](https://miro.medium.com/max/2000/1*AdwM144pGoIBwzdVMV8VnQ.gif)

I'm really excited for what future brings. For now I'm gonna go dogfeed and battle test this library. See ya later.

{% github Marcisbee/exome no-readme %}