
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.
Simple, predictable state management for JavaScript applications
Installation • Quick Start • Documentation • Examples
ControlleX is a framework-agnostic state management library designed for developers who want:
Unlike complex solutions like Redux, ControlleX requires no boilerplate, no action constants, and no middleware setup.
npm install controllex
import { createStore } from 'controllex';
// Create a store with initial state
const store = createStore({
initialState: {
count: 0,
user: null
}
});
// Read state
console.log(store.getState().count); // 0
// Update state
store.setState({ count: 1 });
// Update with current state
store.setState(state => ({ count: state.count + 1 }));
// Subscribe to changes
const unsubscribe = store.subscribe(() => {
console.log('State changed:', store.getState());
});
// Stop listening
unsubscribe();
import { createStore } from 'controllex';
import { useStore } from 'controllex/react';
// Create your store
const counterStore = createStore({
initialState: { count: 0 }
});
// Use in components
function Counter() {
const count = useStore(counterStore, state => state.count);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => counterStore.setState(s => ({ count: s.count + 1 }))}>
Increment
</button>
</div>
);
}
Organize your state into logical slices:
import { createSlice, createStore } from 'controllex';
// Define a counter slice
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment: (state) => ({ ...state, value: state.value + 1 }),
decrement: (state) => ({ ...state, value: state.value - 1 }),
incrementBy: (state, amount: number) => ({
...state,
value: state.value + amount
}),
}
});
// Create store with the slice's initial state
const store = createStore({
initialState: counterSlice.getInitialState()
});
// Use auto-generated actions
const action = counterSlice.actions.increment();
const newState = counterSlice.reducer(store.getState(), action);
store.setState(newState);
Keep your state across page reloads:
import { createStore } from 'controllex';
import { persist } from 'controllex/plugins';
const store = createStore({
initialState: {
theme: 'dark',
user: null,
temporaryData: []
}
});
// Persist only specific keys
const persistedStore = persist(store, {
key: 'my-app-state',
whitelist: ['theme', 'user'], // Don't persist temporaryData
});
Full documentation is available in the /docs/en folder:
import { createStore } from 'controllex';
interface Todo {
id: number;
text: string;
completed: boolean;
}
const todoStore = createStore({
initialState: {
todos: [] as Todo[],
filter: 'all' as 'all' | 'active' | 'completed'
}
});
// Add todo
const addTodo = (text: string) => {
todoStore.setState(state => ({
todos: [...state.todos, { id: Date.now(), text, completed: false }]
}));
};
// Toggle todo
const toggleTodo = (id: number) => {
todoStore.setState(state => ({
todos: state.todos.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
)
}));
};
// Remove todo
const removeTodo = (id: number) => {
todoStore.setState(state => ({
todos: state.todos.filter(todo => todo.id !== id)
}));
};
import { useStore } from 'controllex/react';
function TodoList() {
const todos = useStore(todoStore, state => state.todos);
return (
<ul>
{todos.map(todo => (
<li key={todo.id}>
<input
type="checkbox"
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
/>
<span style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>
{todo.text}
</span>
<button onClick={() => removeTodo(todo.id)}>Delete</button>
</li>
))}
</ul>
);
}
See API_CONTRACT.md for the complete API reference.
| Function | Description |
|---|---|
createStore(config) | Creates a new state store |
createSlice(config) | Creates a slice with auto-generated actions |
| Method | Description |
|---|---|
store.getState() | Returns current state |
store.setState(partial | updater) | Updates state |
store.subscribe(listener) | Subscribes to changes |
| Hook | Description |
|---|---|
useStore(store, selector?) | Subscribe to store with optional selector |
createStoreHook(store) | Create a typed hook for a store |
useStoreDispatch(store) | Get the setState function |
| Function | Description |
|---|---|
persist(store, config) | Add persistence to a store |
clearPersistedState(key) | Clear persisted state |
We welcome contributions! See CONTRIBUTING.md for guidelines.
MIT © Plinio Mabesi
Built with ❤️ for the JavaScript community
FAQs
A simple, predictable state management library for JavaScript applications
We found that controllex demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer 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.