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

jotai-reform

v1.0.16

Published

👻 Jotai with infinity gauntlet

Readme

Jotai Reform

This library aims to provide a new way of using Jotai.

Jotai in itself is an awesome state manager with the convenience of using atoms and making a store instantly. Although using Jotai is kind of different than other state management libraries.

Here are a few common issues with Jotai I face in my projects:

Bad code management. Because of the simple approach of using atom and useAtom hook, Jotai made it easy to mutate a state but soon in larger projects, devs start to lose track of their code. Look at this simple code example:

  const [result, setResult] = useAtom(resultAtom)

setResult((prev) => ({ ...prev, open: false }))

Do you have any idea what this code is about? Me neither! But I wrote that. Now this issue can be solved by wrapping the state change in a meaningfully named function:

 const closeModal = () => {
    setResult((prev) => ({ ...prev, open: false }))
  }

Great, now I know it's being used to close the modal. But wait, what about reusability like reducers or like we do in Zustand? What is i need to use this same functionality in multiple components?

// example in zustand
const useStore = create((set) => ({
  count: 1,
  closeModal: () => set((state) => ({ ...state, open: false })),
}))

// no need to redefine the closeModal and also it increased readability

Now Jotai doesn't give us this out of the box. Well, that's why you need to start using jotai-reform from now on. jotai-reform provides you multiple benefits of using Jotai with ease.

Let's see some of the functions of jotai-reform:

Initialization

// wrap your application with provider from `jotai-reform`

import { createStore } from "jotai";
import { Provider } from "jotai";
const store = createStore();

<Provider store={store}>
  <App />
</Provider>

// using with next js 
"use client";

import { createStore, Provider } from "jotai";
import React, { PropsWithChildren } from "react";

const store = createStore();

export default function JotaiProvider(props: PropsWithChildren) {
  return <Provider store={store}>{props.children}</Provider>;
}

createAtom

createAtom is a wrapper around atom:

    const [useStore, storeAtom] = createAtom(initialState, (set, states, get) => ({...methods}));

createAtom has 2 arguments: 1st is your initialState, 2nd is your methods.

What are methods?

Methods are like reducers to perform any actions in your store. like in the prev examples increment is a method

Return type of createAtom

createAtom returns an array with 2 elements:

const [useStore, storeAtom] = createAtom(initialState, (set, states, get) => ({
  increment() {
    set({ count: states.count + 1 });
  },
}))

Let's see it in action:

const [useStore, storeAtom] = createAtom({ count: 0 }, (set, states, get) => ({
  increment() {
    set({ count: states.count + 1 });
  },
}));

// use storeAtom with useAtom
const [state, setStates] = useAtom(storeAtom);

useStore

// calling useStore hook will give an array 
const [states, methods, setStates, resetStore] = useStore()

// get the states from states
console.log(states.count);

// use methods to call any methods
methods.increment()

// use setState to manually update the states
setStates(p => ({count: p + 1}))

// resetStore will reset the store to its initial state
resetStore()

Using methods in jotai-reform

// in createAtom you have to pass your methods to the callback function

createAtom({count: 0}, (set, states, get) => ({}))

// in this callback you will return an object with methods

createAtom({count: 0}, (set, states, get) => ({
    increment: () => set({count: 1}) // use set to update the state
}))

// by default set reassigns the store value with the new given value
// so the new value will be {count: 1}; if you had another value in that object, it will be removed

//Example
createAtom({count1: 0, count2: 0}, (set, states, get) => ({
    increment: () => set({count1: 1}) // new store value {count1: 1} (count2 is removed)
}))

// to fix this issue you can pass the states to the set function

//Example
createAtom({count1: 0, count2: 0}, (set, states, get) => ({
    increment: () => set({...states, count1: 1}) // new store value {count1: 1, count2: 0}
}))

// the states parameter gives you all the current states of that store `states.count`

// use of `get`
// Now sometimes you need a value from another store/atom; for that, you can use the get function

//Example 
createAtom({count1: 0, count2: 0}, (set, states, get) => ({
    increment: () => set({...states, count1: get(anotherStoreAtom).anyValueFromThatStore}) 
}))

useResetAtoms

Now out of the box, jotai doesn't support resetting selective atoms (not talking about resettable atoms) or resetting the entire store.

Imagine this: you have 5 atoms you have to reset after a user logs out. You can use atomWithReset, but yeah, good luck calling const reset = useResetAtom(myAtom) 5 times and the reset function 5 times as well.

Well, well, well, we have a new approach to reset multiple atoms:

const reset = useResetAtoms();

// call the reset function
reset();
// that's it; it will now reset the entire store

// but what if I just want to reset some particular atoms/stores? It's easy:
reset({resetAtoms: [atom1, atom2]})

// that's it; atom1 and atom2 will now be reset

// but what if I want to reset the entire store excluding some particular atoms?

// easy:
reset({ignoreAtoms: [atom1, atom2]})

// the entire store will now be reset except atom1 and atom2