What is a state manager exactly? A state manager is a smart module that is capable of retaining session data (of an application or web application) and reacting to changes in the data.
Are you a web developer? Ever used libraries such as Redux, Mobx or Zustand? Congratulations! You have used a state manager.
I remember my first days trying to set up (the old) Redux for React. I get PTSD just thinking about all the unnecessary complications - dispatchers, reducers, middleware! I just wanted to declare some variables, please make it stop.
It was an over-engineered, bloated library that EVERYBODY used! And for some crazy, unknown reason, it was the industry standard back then.
Some backstory
One night back in 2021 when I could not fall asleep, I aimlessly opened GitHub and noticed my old college course teacher (which I followed on GH) uploaded an assignment for his current students. The assignment required the students to create a Pokedex website using a public Pokemon API. The goal was to implement it in Javascript (without frameworks or libraries because his current students were web-dev beginners who were still learning the basics of Javascript and development).
As a joke, and mainly because I couldn't sleep, I started working on my Pokemon website. Eventually, I was able to create something viable, without using any external libraries.
But along the way, I struggled...
You see, I was so used to having a state manager, that the requirement of building even a simple, two-page application without using external frameworks or libraries got me thinking - Why do state managers have to be so complicated? It's just variables and events.
Long story short, I found myself hacking together a super-simple state manager module at 2 AM, just to manage the state of my Pokemon web app. I deployed my site to GitHub pages and forgot all about it.
A few months went by, but for some reason, I kept thinking about my state management solution now and then... You see, it had something other libraries didn't have - IT WAS BRAIN DEAD SIMPLE.
"Hey!" I thought to myself, "I should rewrite it as an NPM package".
That same night, I did exactly that - I wrote it as an independent NPM package. At the end of it all, it weighed 2kB (compared to Redux's 150kB), had zero dependencies and was so dead simple to use, that you could have set it up in just 3 lines of code.
I called it VSSM
Stands for Very Small State Manager.
You can check out the source code on GitHub. Also, take a look at the documentation site that is built with React and VSSM.
The following day, I published my NPM package, and once again forgot all about it.
Later that same year, I interviewed in two different companies for a full-stack developer role. I aced the interviews of the first company, which was a very established tech company. As a part of the interview process, they asked me to tell them about whether I code in my free time or if there are any open source projects I contributed to and so on.
The only cool thing I did back then was VSSM, so I told them about it. They were impressed with the idea that I built a "Redux alternative" all on my own.
On the other hand, I failed miserably in the second company's interview. I had blackouts, I was nervous and could not answer simple questions such as
"Does React re-render the entire application upon state changes, or does it only update the affected components and their children when using Redux?"
"It re-renders the whole app every time the state is updated", I said.
I was very nervous, haha, obviously I knew the correct answer was "It only renders the registered components and possibly their affected children".
To this day I have no idea why company No. 2 decided to give me a second chance. They invited me over for another interview (YES!).
During my second interview, they asked me to tell them about whether I code in my free time, open source contributions, you know the drill. The interviewer looked very pleased when I told him about my little side project, it seemed he liked me just for the fact that I coded a state manager from scratch.
I guess that was the case because I also failed the second interview (ran out of time during the coding challenge) but still got an offer. Company No. 1 intended to send me an offer but I had already signed my offer with Company No. 2.
My bottom line is - the fact I built VSSM helped me get both offers.
How did I do it?
Did you know that Javascript has all the functionality needed to monitor variable changes already built in?
It's called a Proxy (and it's magic).
A Javascript proxy is an additional layer of logic between the code and the assignment of variables.
If you were to wrap an object in a proxy, you could decide to log its values to the console every time it is updated, without doing anything but assigning a new value to the object.
const target = {
v: "hello"
}
const proxyTarget = new Proxy(target, {
set: (target, property, value) => {
console.log(`${property} is now ${value}`);
target[property] = value;
return target[property];
}
});
proxyTarget.v = "world!" // v is now world!
VSSM is built on proxies, it creates a layer between variable assignment and the rest of the code. Using a Proxy, you can set setters, getters and implement any sort of logic whenever the value of the target is manipulated or requested.
VSSM is a bit more than just a proxy, it's an assortment of intelligent proxies that know whether the value you assigned to the variable is its new value or a callback method.
For example, using VSSM you can set a state, listen to changes and emit an event with just a few lines of code.
import { createVSSM, createState } from 'vssm';
import { getVSSM } from 'vssm';
// Create the initial state
createVSSM({
user: createState('user', {
address: ''
})
});
// Get the user proxy reference
const { user } = getVSSM();
// Listen to events on user.address
user.address = () => {
console.log(`Address updated! the new address is ${user.address}`);
};
// Emit the mutation event
user.address = 'P.Sherman 42 Wallaby Way, Sydney'
As you can see, I made sure my state manager was as simple as they could be. My goal was to get rid of having to wrap your head around reducers, middlewares and extremely complicated configurations just to assign some variables.
Now, everything works by assigning variables! Want to set up a listener? Assign a callback function to the variable. Want to edit the value and emit an event? Just assign a new value.
To this day I don't understand why popular state managers have to be so complex, maybe I never will.
I encourage you to go ahead and read all about Javascript Proxies on MDN Web Docs.
What is the conclusion of all of this?
Passion for what you do is key, I think.
I built VSSM just to push my limits and publish a reasonable NPM package. It managed to impress interviewers and peers and got me into different positions ever since.
Nobody will ever use VSSM, it will not be popular. I was aware of this fact when I published it to NPM. Yet I still chose to do it to the best of my abilities, because I had a passion for doing something that I conceive is better than the industry standard. I knew I could make something that had to be better, even if it meant it was just better for me.
Even though VSSM is laying dead in the NPM graveyard, it brought me a lot of value and is continuing to do so because of this article.
The best way to get a development job is to build amazing things, even if you think it all has been done before - build it better. Even if you think no one will ever use it, what is the point? - Build it now, value will come later.
Do not underestimate your abilities, if you believe they are lacking, know that you will improve. Go out there and build projects that bring value, one small step at a time.
Good luck on your engineering journey.
Top comments (61)
I did a similar library.
Looks great! Did you also use Proxies?
Yes, I used proxy too.
MVC doesn't scale. Redux has boilerplate, but it scales.
I never said this should replace Redux :) I also don't know if this scales, but complexity wise Redux doesn't have to scale, it's extremely complicated from the get-go.
There is beauty in simplicity.
Come on. Complexity isn't binary. Let's say Redux is 3 out of 10 complex. This solution is 1 out of 10 complex for simple apps. Redux will grow to 5 out of 10 complex maximum, well this will grow to 10 out of 10 complex.
And when you say this doesn't replace Redux, do you mean they should use this inside a reducer?
Even if this could grow to a "10 out of 10" (whatever that means) complexity, you sure seem to have a very emotional reaction towards a state manager PoC that nobody uses. Have fun with that. Here is a quote from the readme:
"This project is not a replacement for other state management libraries, it's here to give a tiny, native solution for projects that wish to stay relatively small, and still enjoy state management".
Don't worry, people will use this. They thought Valtio was a good idea github.com/pmndrs/valtio
I'm not emotional, just direct. I have experience with dozens of state management libraries and I see what happens with each of them. People misuse Redux and it actually does turn into spaghetti code too. I'm about to write an article about that.
I just think it's a false trade-off between simplicity and scalability. I really don't like that the response to unidirectional data flow is to toss it out rather than improve upon the existing tools.
And it doesn't matter what your README says, if two things solve the same problem, even different sides of it, they're going to compete. People will use one over the other. They are substitutes. In a year I bet we see an article like "Why I chose VSSM over Redux" (or JΕtai or Zustand etc). Actually, that's kind of what this article is already.
If it doesn't matter what my readme says than it doesn't matter what I say.
Have fun with your experience with state management libraries, I will just keep doing me :)
P.S English is not my native language, not everybody is from the US.
I didn't notice any English mistakes.
Creating a state management library takes work and I respect that. It's a great learning exercise as well. But beyond that, you might be wasting your time, and I say that out of empathy. There are a lot of simple solutions out there already, and I would in particular recommend looking into Valtio and JΕtai. I created StateAdapt, but if bundle size matters most to you, don't use it - it's around 10kb. But if bundle size matters most to you, I'd recommend using SolidJS or Qwik, since both have built-in mechanisms somewhat similar to what you've created. I think Qwik even uses proxies too.
We centrally don't need another state management library, but its good to explore different solutions and implementations, which Is what i believe this VSSM is, its perfectly fine and a great way to learn, and its not using anything other than what JS does natively.
When you've never touched a complex application
Sorry @mfp22 using your own phrase just being direct. You are wrong. Comparing this in terms of complexity with redux and stating that at most redux is a 5/10 in a complex application is just an incorrect fact. Redux is well known to be one of the least liked solutions due it's complexity. Even after you understand it and I personally like it and used to promote it before will always known that by many developers it is not a liked solution because of it's complexity.
Also know that you did not share your opinion alone it is clear it was an emotional response to protect redux which is completely out of the scope of the conversation in this post. I suggest next time don't overdue it and just share
Redux was mentioned in the 2nd paragraph. Redux has limitations. If you think Redux gets beyond 5/10, I look forward to you finding out what 6+ actually looks like, because it's only possible when event handlers have to do too much work. This is always happens when state update logic cannot be colocated with state declarations. It's the reason Flux was created. I recommend watching the original Flux + React talk a few times. Just because you haven't encountered the same problems as the Facebook team yet, doesn't mean you won't.
(Also I never use Redux anymore. It's just better than the knee-jerk reactions to it that never tried to understand what problems it was trying to solve.)
Mike whatβs the point of arguing about such opinionated things? Youβve made your point, too bad it was not in a very nice way, but we will get over that. What is the purpose of this?
It must be nice not being opinionated like me. I can't help that when I see "Redux is too complicated" I get flashbacks from the battles I've fought in dozens of MVC codebases. I'm just sharing what I've learned. I would appreciate it if I were you. It's less nice to say nothing. I'm done. Good luck.
Alright mate
Valtio over Redux for any app size I disagree on all points from @mfp22
Give me any complex app on GitHub using Valtio and I'll make it simpler. By complex I don't mean "big" like 30 pages - I mean pages with multiple kinds of events and effects, maybe heavily asynchronous. Maybe a real-time dashboard or something. I'll diagram the data flow and show that the number of relationships and things to keep track of decreases. I'll use StateAdapt, which is more unidirectional than Redux.
Anything that uses redux is already doomed
Sure Jan
Something I notice is that you may be picking out only one value, but you are always returning the entire state from the getter function. I get that you're not working on it any more, but I'd look up "dependency injection" to specify the data you want in the getter function.
I agree, it can definitely be improved (in more than one way).
Before writing this article I went over the code for a few minutes and noticed some issues.
I don't think I will be working on it, but if you really feel like it I don't mind letting others contribute. (Or we can just leave it as it is and take mental notes, lol).
I felt the same haha. We just want something simple, 0 deps, and performant π€·ββοΈ
Good article; keep building and creating!
Jotai and Zustand - both manage to be simple, 0 deps and performant.
And they scale as good as Redux as well.
Thanks for sharing!
Thanks for the support !
qwik
framework is also use Proxy behind of scene withuseStore
, this is one of main reason why I preferred compared react. But my daily based jobs depend on react and I think for a couple of years React stay as leading framework/library for UX.Heard about qwik, I'll have to check it out!
I wonder why a Proxy is not built into the JS object, it is a bit limiting. There is a need, as in the Pisma project, which essentially made it but with an extra build step. Python has setattr and getattr for this purpose.
Yea, there is definitely a need. I would actually love to see that in the future.
By the way I like your lib style, JS with d.ts π€© interesting and original approach, well done π I like that you have subscription implemented I would put more thought into definig subscriptions, it looks a bit ambiguous.
Thanks! I honestly dislike TS quite a lot but it has itβs uses. The subscription model is definitely ambiguous, far from perfect. Honestly if I were to rewrite it today Iβd probably do it differently. Either way, this lib is more of a novelty than anything at this point π
πͺπͺπ―. State management libraries don't have to be so complicated.
For the react thing, i am one of the the software engineer behind the web development framework.
github.com/FridayCandour/cra...
Don't forget to share.
You never know, maybe it becomes popular one day :)
Do you think it can be done by removing the additional createState function, and just initialize it with createVSSM
What do you think about me contributing just for the fun of it?
Feel free to, could be fun π
I think itβs possible!
To showcase your passionate projects, you have to land on an interview first and how do you that in 2023? π
Nice take. Passion will push you far in programming world. Keep building things and improving your craft. The job will find you.
Haha yeah, you sure have to land an interview first.
I think that it is really hard for beginners and graduates, for sure. But do what you have to do, upsell yourself. Send messages to employees, to HR, don't be shy! Be professional and always interact with other people in the community.
Once you get to somebody on the phone, act like you are the most sophisticated web developer out there.
Just make sure you do not lie, and remember you do have to know enough to give off a confident vibe, but when you get the first offer it's much, much easier.
I like this a lot more than Redux and Context API from what I read in your post, I wonder how it works implemented into a React UI, Great job!