store2state is a robust and flexible state management library for JavaScript and TypeScript, designed with a focus on React integration and easy extensibility to other frameworks.
It provides a powerful Store class, AsyncAction utility for async flows, and custom React hooks for reactive state access.
π store2state is participating in Hacktoberfest 2025!
Whether youβre new to open source or an experienced TypeScript dev β weβd love your contributions!
Weβve labeled issues with:
good first issueβ beginner-friendlyhelp wantedβ community support neededhacktoberfestβ counts toward Hacktoberfest contributions
π‘ All merged, approved, or
hacktoberfest-acceptedpull requests will count for Hacktoberfest 2025!
- Star this repo π
- Fork and clone it locally
- Pick an issue labeled
good first issueorhelp wanted - Create a feature branch
- Make your change (bug fix, doc update, new feature)
- Open a Pull Request with a clear description
You can also propose new ideas or file improvement issues!
Here are a few easy and impactful ways to contribute:
- π§ Docs: Improve README examples or add JSDoc comments
- π§© React Hooks: Add a hook for derived/computed state
- π§ͺ Testing: Add unit tests for the
StoreorAsyncActionclasses - π§° TypeScript: Improve generic types for better inference
- βοΈ New Feature: Add
createVueStoreorcreateSvelteStorewrappers - πͺΆ Performance: Optimize shallow comparison logic
- De-centralized state management with subscriptions
- Efficient state updates with shallow comparison
- React hooks for easy integration (
useStore,useStoreSelector) - Asynchronous action handling with status tracking and cancellation
- TypeScript support for type-safe state management
npm install store2stateimport { createStore } from "store2state";
const initialState = { count: 0 };
const store = createStore(initialState);import { useStore } from "store2state";
function Counter() {
const { get, set } = useStore(store);
return (
<div>
<p>Count: {get().count}</p>
<button onClick={() => set((state) => ({ count: state.count + 1 }))}>
Increment
</button>
</div>
);
}import { useStoreSelector } from "store2state";
function CountDisplay() {
const count = useStoreSelector(store, (state) => state.count);
return <p>Count: {count}</p>;
}import { createAsyncAction, Status } from "store2state";
const fetchUserAction = createAsyncAction(
store,
async (store, setStatus, userId) => {
setStatus(Status.LOADING);
try {
const response = await fetch(`/api/users/${userId}`);
const user = await response.json();
setStatus(Status.SUCCESS, user);
return user;
} catch (error) {
setStatus(Status.ERROR, error);
throw error;
}
}
);import { createStore, useStore } from "store2state";
const formStore = createStore({ name: "", email: "" });
export function ContactForm() {
const { get, set } = useStore(formStore);
const handleChange = (e) => {
const { name, value } = e.target;
set((state) => ({ ...state, [name]: value }));
};
return (
<form>
<input
name="name"
value={get().name}
onChange={handleChange}
placeholder="Your name"
/>
<input
name="email"
value={get().email}
onChange={handleChange}
placeholder="Your email"
/>
<button type="submit">Submit</button>
</form>
);
}import { createStore, useStore } from "store2state";
const settingsStore = createStore({
theme: localStorage.getItem("theme") || "light",
});
settingsStore.subscribe((state) => {
localStorage.setItem("theme", state.theme);
});
export function ThemeSwitcher() {
const { get, set } = useStore(settingsStore);
return (
<button
onClick={() => set({ theme: get().theme === "light" ? "dark" : "light" })}
>
Toggle Theme (Current: {get().theme})
</button>
);
}import { createStore, createAsyncAction, useStore } from "store2state";
const userStore = createStore({ user: null, loading: false });
const fetchUser = createAsyncAction(userStore, async (store, setStatus, id) => {
setStatus("loading");
const res = await fetch(`/api/users/${id}`);
const data = await res.json();
store.set({ user: data });
setStatus("success");
});
export function UserProfile({ userId }) {
const { get } = useStore(userStore);
React.useEffect(() => {
fetchUser(userId);
}, [userId]);
if (get().loading) return <p>Loading...</p>;
if (!get().user) return <p>No user found.</p>;
return <p>Welcome, {get().user.name}!</p>;
}(unchanged β your original section here)
- Decouple React integration into
@store2state/react - Add framework-agnostic hooks (Vue, Svelte, Solid)
- Add unit tests and benchmarks
- Add middleware support (e.g., for logging or persistence)
Pull requests are welcome! Before submitting:
- Ensure your code is formatted with
prettier - Include tests for new features
- Update or improve documentation if applicable
This project is licensed under the MIT License.