High-performance React state management with fine-grained reactivity
Mesa provides automatic dependency tracking and path-based subscriptions, ensuring only the components that need updates actually re-render. Zero dependencies, minimal bundle size, maximum performance.
Only re-render components that use changed data. Mesa automatically tracks dependencies and updates only what's necessary.
Three core functions: proxy(), useStore(), and useInitSync(). No complex selectors, no manual optimizations.
~1KB gzipped with no external dependencies. Built for modern React applications.
npm install mesa-reactimport { proxy, useStore, useInitSync } from "mesa-react";
// Create a reactive store
const store = proxy({
count: 0,
user: {
name: "John",
age: 30,
},
});
// Use in components
function Counter() {
const count = useStore(store, (s) => s.count);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => store.count++}>Increment</button>
</div>
);
}
function UserInfo() {
const userName = useStore(store, (s) => s.user.name);
const userAge = useStore(store, (s) => s.user.age);
return (
<div>
<p>Name: {userName}</p>
<p>Age: {userAge}</p>
</div>
);
}Mesa uses JavaScript Proxies to automatically track which properties your components access. When you use useStore(), Mesa creates a subscription to only the specific paths you read.
function MyComponent() {
const userName = useStore(store, (s) => s.user.name);
// Only subscribes to 'user.name' property
return <div>{userName}</div>;
// Will re-render only when user.name changes
}Mesa tracks deep object access automatically:
function DeepComponent() {
const theme = useStore(store, (s) => s.user.profile.settings.theme);
// Only subscribes to this specific path
return <div>{theme}</div>;
}Mesa handles immutable updates automatically:
// These all work seamlessly
store.count = 5;
store.user.name = "Jane";
store.items.push(newItem);
store.nested.deep.value = "updated";const store = proxy({
items: [],
get totalCount() {
return this.items.length;
},
get expensiveValue() {
return this.items.reduce((sum, item) => sum + item.value, 0);
},
});
function Summary() {
const totalCount = useStore(store, (s) => s.totalCount);
const expensiveValue = useStore(store, (s) => s.expensiveValue);
return (
<div>
<p>Total Items: {totalCount}</p>
<p>Total Value: {expensiveValue}</p>
</div>
);
}const store = proxy({
data: null,
loading: false,
error: null,
});
function DataComponent() {
// Declarative initialization - runs once per component tree
useInitSync(store, async (state) => {
state.loading = true;
try {
const response = await fetch("/api/data");
state.data = await response.json();
} catch (err) {
state.error = err.message;
} finally {
state.loading = false;
}
});
const data = useStore(store, (s) => s.data);
const loading = useStore(store, (s) => s.loading);
const error = useStore(store, (s) => s.error);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
if (!data) return <div>No data</div>;
return <div>{JSON.stringify(data)}</div>;
}function LocalCounter() {
const localStore = useMemo(() => proxy({ count: 0 }), []);
const count = useStore(localStore, (s) => s.count);
return <button onClick={() => localStore.count++}>Count: {count}</button>;
}Mesa tracks only the specific paths your components access:
function Header() {
const userName = useStore(store, (s) => s.user.name);
// Only subscribes to 'user.name' path
return <header>Welcome, {userName}!</header>;
}
function Sidebar() {
const sidebarContent = useStore(store, (s) => s.sidebar.content);
// Only subscribes to 'sidebar.content' path
return <aside>{sidebarContent}</aside>;
}
function Main() {
const content = useStore(store, (s) => s.content);
// Only subscribes to 'content' path
return <main>{content}</main>;
}Only components that actually use changed data will re-render:
function CountComponent() {
const count = useStore(store, (s) => s.count);
// Only re-renders when count changes
return <div>Count: {count}</div>;
}
function NameComponent() {
const name = useStore(store, (s) => s.name);
// Only re-renders when name changes
return <div>Name: {name}</div>;
}
// When store.count changes, only CountComponent re-renders
// When store.name changes, only NameComponent re-rendersCreates a reactive store from an initial state object.
const store = proxy({
count: 0,
user: { name: "John" },
});Hook to subscribe to store changes. Returns the selected value.
const count = useStore(store, (s) => s.count);
const userName = useStore(store, (s) => s.user.name);Hook for declarative state initialization with atomic updates.
// Object initialization
useInitSync(store, {
data: initialData,
initialized: true,
});
// Function initialization
useInitSync(store, async (state) => {
const data = await fetchData();
state.data = data;
state.loading = false;
});
// With dependency tracking
useInitSync(store, async (state) => {
const userData = await fetchUser(userId);
state.user = userData;
}, { deps: [userId] });// Before (Redux)
const mapStateToProps = (state) => ({
count: state.counter.count,
user: state.user,
});
// After (Mesa)
const count = useStore(store, (s) => s.count);
const user = useStore(store, (s) => s.user);// Before (Zustand)
const count = useStore((state) => state.count);
const increment = useStore((state) => state.increment);
// After (Mesa)
const count = useStore(store, (s) => s.count);
const increment = () => store.count++;// Before (Context)
const { state, dispatch } = useContext(MyContext);
// After (Mesa)
const count = useStore(store, (s) => s.count);MIT License - see LICENSE for details.
Built with ❤️ for the React community.