npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vutr/gstate

v2.0.2

Published

The best Hook-based State-Manager for React your $$$ cannot buy!

Readme

There has been numerous open-source projects that try to tackle the problem with React shared state, but here is a bad news: most of them are overly complicated, with unfriendly API and introduce way too much brain-load as well as boilerplate code.

What if we can have a Library with minimal APIs and flat-learning curve that will not take us more than 5 minutes to grasp? One of the few best stuffs that may fall in such cateogry I would honor here is zustand and redux-zero. Redux-zero is great for those who love to stick with Redux's style, while zustand is nice for modern adopters who favor react-hooks.

Yet though I love hooks, I don't feel quite right with zustand, meanwhile I'm done with Redux for ages already. Well that means I have to do it myself - the way I like. And I hope you would like it as well.

About The Project

GreenState is a state-management library that helps develop shared or global state between components using the sweet React-Hooks. The Aim is to provide one of the friendlies API that - as Steve Job used to say - It just works!.

Let's say, you declare **Your State**, ask a key name - that's simple -  and GreenState returns just its value to you??

You can use it to create as many stores as you like. The APIs are minmal, support all basic cases, including..

  1. Get a single value from Store
  2. Get a group of values from Store
  3. Get a derived-value / composed-value from Store (just like you would with RecoilSelector)
  4. Dispatch an action to update store - either async or non-asynchronous
  5. Intuitive type-hint support with typescript!
  6. Maximum coverage!

Built With

  • typescript
  • that's it!

Getting Started

Prerequisites

This is a React stuff, so naturally you need React - more specifically the version that supports hook - unless you are Gandalf the Grey who can pretty much do whatever he likes without npm!

Installation

Install NPM packages

npm install @vutr/gstate

Usage

  • First, setup your state store with GreenState
// ./state
import { Store } from '@vutr/gstate'

type GlobalState = {
  count: number
  hello: string
}

const state: GlobalState = {
  count: 0,
  hello: 'World'
}

const store = new Store(state)

export const useGValue = store.useGValue
export const useGState = store.useGState
export const useAction = store.useAction
  • Second, use The-Damn-Store!! Your precious state will be shared between components.
// ./component
import { useGValue, useGState, useAction } from './state'

const TestOne = () => {
  const [cnt, setCnt] = useGValue('count')
  const handleClick = () => setCnt(cnt + 1)
  return (
	<div>
	  <button onClick={handleClick} data-testid="inc-1">Increase</button>
	  <p data-testid="message">{`count = ${cnt}`}</p>
	</div>
  )
}

const TestTwo = () => {
  const [obj, setObj] = useGState('count', 'hello')
  const handleClick = () => setObj({ count: cnt.count + 3 })
  return (
	<div>
	  <button onClick={handleClick} data-testid="inc-3">
		Increase
	  </button>
	</div>
  )
}

APIs

Store(intialState: Record<string, any>, derivedState?: (state) => Record<string, any>)

  • Aside from defining initialState, you can optionally have derivedState passed to Store. The derivedState is something just like RecoilSelector, or React's getDerivedState
  • Combine everything we have something like...
import { Store } from '@vutr/gstate'
type State = {
  count1: number
  count2: number
}

type DerivedState = {
  total: number
  divided: number
}

const state: State = {
  count1: 1,
  count2: 1,
}

const derived = (state: State): DerivedState => ({
  total: state.count1 + state.count2,
  divided: state.count1 / state.count2,
})

const store = new Store(state, derived)

export const useGValue = store.useGValue
export const useGState = store.useGState
export const useAction = store.useAction
export const useDerivedValue = store.useDerivedValue
export const useDerivedState = store.useDerivedState

useGValue(key: keyof State) => [State[key], Dispatch<State[key]>]

  • get and set a single value from State using its key.
import { useGValue } from './state'
const [cnt, setCnt] = useGValue('count')

console.log(cnt) // 0
console.log(setCnt) // Function(x: number) => void; type inferred from the value of `count`
setCnt(1)
console.log(cnt) // 1

useGState(...keys: keyof State[]) => [Pick<State, keys>, (obj: Partial) => void]

  • get and set a collection of value from State using their keys.
import { useGValue } from './state'
const [obj, setObj] = useGState('count', 'hello')
console.log(obj) // { count: 0, hello: 'World'}
console.log(setObj) // Function(x: Partial<State>) => void
// type inferred from the value of `keys` passed to useGState

useAction(action: Action<State, args>) => (args, { get, set }) => Partial | void

type Action<T extends StateObj, K> = (value: K, { get: StateGetter<T>, set: StateSetter<T> }) => (
  Partial<T> | void | Promise<Partial<T> | void>
)
  • Define an action and use it to update the State
  • If an action return part of the State, it will be merged to the State, otherwise nothing will happen
  • Action can be either asynchronous or synchronous - meaning async/await works just fine
  • get State or set State freely
const { useAction, useGValue, StateSetter } = new Store(state)

const increase = (num, { count }) => {
  return { count: count + num }
}

const asyncIncrease = async (num: number, { get, set }) => {
  await sleep(300)
  set({ count: get().count + num })
}

let greet = ''
const changeGreet: Action<GlobalState, string> = (country, { set }) => {
  greet = `Hello ${country}`
  set({ hello: 'Ciao' })
}

const TestOne = () => {
  const cnt = useGValue('count')[0]
  const inc = useAction(increase)
  const asinc = useAction(asyncIncrease)
  const greeting = useAction(changeGreet)

  const clickAsync = () => asinc(3)
  const handleClick = () => inc(4)
  const makeGreet = () => greeting('Vietnam')

  return (
	<div>
	  <button onClick={handleClick} data-testid="inc-4">Increase</button>
	  <button onClick={makeGreet} data-testid="greet">Greet</button>
	  <button onClick={clickAsync} data-testid="asinc-3">Async</button>
	  <p data-testid="message">{`count = ${cnt}`}</p>
	</div>
  )
}
  • useDerivedValue(key: K extends keyof DerivedState) => DerivedState[K]

  • useDerivedState(...keys: Array) => Pick<DerivedState, keys>

Example

type State = {
  count1: number
  count2: number
}

type DerivedState = {
  total: number
  divided: number
}

const state: State = {
  count1: 1,
  count2: 1,
}

const derived = (state: State): DerivedState => ({
  total: state.count1 + state.count2,
  divided: state.count1 / state.count2,
})

const { useGValue, useDerivedValue, useDerivedState } = new Store(state, derived)

const TestOne = () => {
  const total = useDerivedValue('total')
  const totalObject = useDerivedState('total', 'divided')

  return (
	<div>
	  <p data-testid="total">{`total = ${total}`}</p>
	  <p data-testid="derived">{`derived = ${totalObject.divided}`}</p>
	</div>
  )
}

Contributing

Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.

License

Distributed under the MIT License. See LICENSE for more information.

Contact

Vu Tran - [email protected]

Project Link: https://github.com/vutran1710/Green-State