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 🙏

© 2024 – Pkg Stats / Ryan Hefner

klyva

v0.10.0

Published

Scalable state management for React.

Downloads

32

Readme

🪓 klyva

Scalable state management for React.

Minimal API, with reactive, composable and decomposable state!

📺 10 minute tutorial

How to

Create an atom

A base atom can be constructed by giving the atom a value.

const countAtom = atom(5)

useAtom

The useAtom hook subscribes to changes to the atom, so if it's updated, then this component is notified and updated. The hook is similar to react's useState in that it gives a setState function.

const MyComponent = () => {
  const [value, setValue] = useAtom(countAtom)
  const increase = () => setValue(oldValue => oldValue + 1)
  return <button onClick={increase}>{value}</button>
}

Composition

Atoms are composable. Meaning that you can glue together two atoms using the get function, when any dependant atoms are updated, the derived atom is updated:

const atomOne = atom(10)
const atomTwo = atom(20)
const sumAtom = atom(get => get(atomOne) + get(atomTwo))

Decomposition

You can focus on a smaller part of an atom, to view and update that smaller part (focusedAtom) - which in turn updates the derivee (objectAtom).

const objectAtom = atom({a: 10})
const focusedAtom = focusAtom(objectAtom, optic => optic.prop('a'))

const MyComponent = () => {
  const [value, setValue] = useAtom(focusedAtom)
  const increase = () => setValue(oldValue => oldValue + 1)
  return <button onClick={increase}>{value}</button>
}

See more about optics at: https://github.com/akheron/optics-ts

Usage outside of react

Get value

Use the getValue function to get the atoms current value:

const counterAtom = atom(0)
counterAtom.getValue() // 0

Update it

Atoms have an update function, which can be used to update it outside of react:

const numberAtom = atom(5)

numberAtom.update(6)
numberAtom.update(value => value + 1)

Subscribe

Use the subscribe function to subscribe to changes for this atom:

const counterAtom = atom(0)
counterAtom.subscribe(count => console.log(`The count is: ${count}`))
counterAtom.update(count => count + 1)
// console: The count is: 1

Advanced example

When you have an atom which contains a list, and you want to delegate control of each list item, you can use the useAtomSlice-hook like this:

const listAtom = atom([0,0,0])

const CounterList = () => {
  const counterAtoms = useAtomSlice(listAtom)
  const addCounter = () => listAtom.update(counters => [...counters, 0])
  return (
    <>
      <ul>
        {counterAtoms.map((atom) => <Counter counterAtom={atom} onRemove={atom.remove} />)}
      </ul>
      <button onClick={addCounter}>
        Add counter
      </button>
    </>
  )
}

const Counter = ({counterAtom, onRemove}: {counterAtom: Atom<number>, onRemove: () => void}) => {
  const [count, setCount] = useAtom(counterAtom)
  return (
    <li>
      <button onClick={() => setCount(v => v + 1)}>{count}</button>
      <button onClick={onRemove}>Remove me</button>
    </li>
  )
}

Curious? See codesandbox!

Differences from jotai and recoil

  • No <Provider> needed
  • No key needed for atom
  • More performant: Atoms are minimally expensive to create, and you can create them almost for free in react components.
  • Usage outside of react components is supported, so you can listen to changes and update atoms from outside of a react context.

Install

Using npm

npm i klyva

Using yarn

yarn add klyva