
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
The forbidden love child of Redux and Zustand ❤️🔥👶
Zusdux is a type-safe state management library that combines the best of both worlds from Redux and Zustand. It has a Redux Toolkit-like API, but with Zustand's reduced boilerplate and simplicity. It also has a built-in support for React!
The API is pretty similar to what you'd find in Redux Toolkit's createSlice function, with a leaner signature, and without the need for providers or messing up with async thunks - similar to Zustand.
It has a single function, called createStore, which returns an object with getState, setState, subscribe, useStore, and actions properties.
First, you create a store with the createStore function. It takes an object with initialState and actions properties:
initialState - It's... well... the initial state of your store
actions - An object containing a list of actions that can be performed on the state. The actions can be either synchronous or asynchronous, they can take any
number of arguments, while the first one is a set function that allows you to update the store's stat. The set function can accept either a new state object
that will be shallowly merged with the current state, or a function that receives the current state and returns the new state.
(See Zustand's documentation for more info)
// store.ts
import { createStore } from 'zusdux';
export const { actions, getState, setState, subscribe, useStore } = createStore(
{
initialState: {
name: 'counter',
count: 0,
isLoading: false,
},
actions: {
increment: (set) => {
set((prev) => ({
...prev,
count: prev.count + 1,
}));
},
incrementBy: (set, by: number) => {
set((prev) => ({
...prev,
count: prev.count + by,
}));
},
incrementAsync: async (set) => {
set({ isLoading: true });
await new Promise((resolve) => setTimeout(resolve, 100));
set((prev) => ({
...prev,
count: prev.count + 1,
isLoading: false,
}));
},
setName: (set, firstName: string, lastName: string) => {
set({ name: firstName + ' ' + lastName });
},
},
},
);
Each "store action" is then converted to a "user action" under the store object, which will update the store's state when called:
actions.increment();
actions.incrementBy(5);
await actions.incrementAsync();
actions.setName('new', 'name');
In addition, you can access the current store's state with the getState function, and update it with the setState function:
const currentState = getState(); // { name: 'counter', count: 0 }
setState((prev) => ({
...prev,
count: 5,
}));
const updatedState = getState(); // { name: 'counter', count: 5 }
Similar to Redux, you can also subscribe to the store's state changes:
const unsubscribe = subscribe(() => {
console.log('Current state:', getState());
});
unsubscribe();
And similar to Zustand, you can use the store within your React components:
// Counter.tsx
import { actions, useStore } from './store';
export const Counter = () => {
const { name, count, isLoading } = useStore();
return (
<div>
<h1>{name}</h1>
<p>{isLoading ? 'Loading...' : 'Not loading'}</p>
<p>Count: {count}</p>
<button onClick={actions.increment}>Increment</button>
<button onClick={() => actions.incrementBy(5)}>Increment by 5</button>
<button onClick={actions.incrementAsync}>Increment async</button>
<button onClick={() => actions.setName('new', 'name')}>Set name</button>
</div>
);
};
You can also provide a selector to the useStore function to select a specific part of the store, similar to what you'd do with Redux's useSelector
const count = useStore((state) => state.count);
This way, your component will only re-render when the selected part of the store changes.
As you might've noticed, we don't need a provider at all! 🥳
FAQs
The forbidden love child of Redux and Zustand
We found that zusdux demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.