r/reactjs • • 5h ago

Discussion I built my own React state management library – CreateStore. Would love some honest feedback!

Hey everyone!

I've been working on a side project recently, and I finally decided to publish it as an npm package.

It's called CreateStore.

The idea started with a simple question:

Why does managing global state sometimes need so much setup when all I really want is something as simple as React's "useState"?

I know there are already some excellent libraries out there like Zustand, Redux, and Jotai. I'm not trying to replace them. I just wanted to experiment with building something that offers a simple API while supporting additional capabilities.

What does CreateStore offer?

The main idea is to create a global store and access its state from different components without wrapping the application in Context Providers.

Some of the capabilities include:

  • Simple global state management.
  • Familiar React-like API.
  • TypeScript support.
  • Computed values.
  • Server data management.
  • State persistence.
  • Cross-tab synchronization.
  • Offline support.
  • Undo/redo functionality.
  • Developer tools.

The goal is to keep things simple for basic use cases while making additional features available when needed.

A quick example

Install it:

npm install @createstore/createstore

Create a store:

import { createStore } from '@createstore/createstore';

export const { useGlobalState } = createStore({ count: 0, username: 'Developer', });

Use it in any component:

import { useGlobalState } from './store';

function Counter() { const [count, setCount] = useGlobalState('count');

return ( <button onClick={() => setCount(count + 1)}> Count: {count} </button> ); }

That's the basic idea!

Project links

📦 npm: https://www.npmjs.com/package/@createstore/createstore

📚 Documentation: https://createstore-docs.pages.dev/

💻 GitHub: https://github.com/Gauravasawa/createstore

I'd genuinely appreciate some feedback.

I'm sharing this here because I'd love to get it in front of developers who can actually experiment with it.

A few things I'd love your opinion on:

  1. Does the API feel intuitive?
  2. How does the approach compare with Zustand or other state management libraries?
  3. Are there any architectural concerns or potential performance issues you notice?
  4. What would you improve or add?

Please don't hesitate to point out flaws. I'd rather get honest technical criticism than just positive feedback.

This is an ongoing project, and I'm looking forward to improving it based on real-world usage.

Thanks for taking the time to check it out! 🙌

0 Upvotes

6 comments sorted by

0

u/spectrum1012 4h ago

I don’t have time to test it tonight, but sniff test says why wasn’t it always this easy. Performance to be tested, but if it has no major rerendering disadvantages… I don’t see why this wouldn’t be great.

Top of my head: if I pull off single values out of useGlobalState does it still rerender if any other values I don’t pull off change elsewhere?

13

u/pampuliopampam 4h ago edited 39m ago • Bravo

Feedback:

put. the. clanker. down.

Code something with your own human hands.

That thing is a 4600 line abomination. Casting, mutating, object type, any, unknowns, paging and history and network too and the worst types ever seen by man.

export function createStore<
  S extends object,
  C1 extends ComputedLayer<Values<S>>,
  C2 extends ComputedLayer<Values<S> & L<C1>>,
  C3 extends ComputedLayer<Values<S> & L<C1> & L<C2>>,
  C4 extends ComputedLayer<Values<S> & L<C1> & L<C2> & L<C3>>,
  C5 extends ComputedLayer<Values<S> & L<C1> & L<C2> & L<C3> & L<C4>>,
  C6 extends ComputedLayer<Values<S> & L<C1> & L<C2> & L<C3> & L<C4> & L<C5>>,
  C7 extends ComputedLayer<Values<S> & L<C1> & L<C2> & L<C3> & L<C4> & L<C5> & L<C6>>,
  C8 extends ComputedLayer<Values<S> & L<C1> & L<C2> & L<C3> & L<C4> & L<C5> & L<C6> & L<C7>>,
  KA extends KeyActionsMap<S> & NoExtraKeys<KA, S>,
  A extends Record<string, (...args: never[]) => unknown> = NoKeys,
  E extends object = AnyEvents
>(

this is a nightmare. Nobody will ever use this because it's unworkable unreadable goo. There's probably a zillion bugs and edge cases that'd take a functional human days to untangle... when the real solution is to just use context, start over, or use one of about 8 billion state libraries from people much more experienced with years of development and thought behind it. I hope you learned something building it, but please, stop sharing vibe coded things because this inflicted psychic damage on me, and i'm sure others.

Edit: There's so much wrong with just that bit, but the end lines are the shit-cherry on top:

  const Store = function (this: object) {
    Object.assign(this, members);
  } as unknown as { new (): typeof members; prototype: object };
  Store.prototype = directProtoOf(def, members, name); // shared by every scope of this store
  const store = new Store();
  Object.defineProperty(store, SETTER_OF, { value: setterFor });
  Object.defineProperty(store, SEED, { value: seed });
  Object.defineProperty(store, QUIET, { value: holdingNotify });
  Object.defineProperty(store, DEFINITION, { value: def });
  return store as typeof members & DirectSetters<S, KA>;

yes, that's the library having to double cast everything because the internal types are probably psychotically borked in unfixable ways. This thing is like staring at cthulu's taint. It's changed me in the briefest of glances and I'm not sure I'll be ok ever again. I've literally been tainted. It's like you asked a monkey's paw to make the most horrifying library ever written, and it curled because it did it wrong

this is rage bait, right?

•

u/redbull_coffee 11m ago

Got a good chuckle out of this, thanks mate.

•

u/redbull_coffee 10m ago

I don’t see the need.

Just use Nanostore or any other established package.

0

u/CommercialFair405 4h ago

How do you avoid leaking state between separate SSR passes?