Getting Started with neutrix
Installation
Add neutrix to your project:
npm install neutrix
Setup for Typescript configuration
To use neutrix with TypeScript, ensure your tsconfig.json has the following configurations:
{
"compilerOptions": {
"target": "ESNext",
"moduleResolution": "node",
"jsx": "react-jsx",
"esModuleInterop": true,
"strict": true,
"skipLibCheck": true
}
}
Core Features Overview
neutrix is a state management library providing the following core capabilities:
Store Management
- State creation and configuration
- Immutable updates
- Batch operations
- Path-based access
Advanced Features
- Computed values with LRU caching
- Suspense support
- Store connections
- Middleware system
- Path optimization
- DevTools integration
- State persistence and migration
React Integration
- Provider system (optional)
- Custom hooks
- Action handling
Core Concepts
Creating a Store
Neutrix provides multiple ways to create a store. createNeutrixStore is the recommended and most flexible approach:
1. Using createNeutrixStore (Recommended):
// You can choose either approach depending on your app’s scale
import { createNeutrixStore } from 'neutrix';
// Hook-based store (simpler)
const useStore = createNeutrixStore({ count: 0 });
// Provider-based store
const { store, useStore, Provider } = createNeutrixStore(
{ count: 0 },
{ provider: true }
);
Store options
All store creators accept these options:
interface StoreOptions {
name?: string; // Store name for DevTools/persistence
devTools?: boolean; // Enable Redux DevTools
persist?: boolean | ((state: any) => any); // Enable localStorage persistence
validate?: (state: State) => boolean | string; // Add validation
migration?: { // Handle persistence migrations
version: number;
migrate: (oldState: any) => any;
};
concurrency?: boolean; // Enable React concurrenct (e.g., startTransition)
onDestroy?: () => void; // Enable React concurrency features
}
State Operations
You can access state in two ways:
// 1. Direct property access (recommended and simpler way too)
const count = useStore(s => s.count);
// 2. Path-based access
const count = useStore(s => s.get('count'));
Updating state:
// 1. Using store.set
useStore.store.set('count', count + 1);
// 2. Batch updates
useStore.store.batch([
['count', newCount],
['lastUpdated', Date.now()]
]);
Computed Values
Computed values are derived state that update automatically when dependencies change:
import { useNeutrixComputed } from 'neutrix';
const fullName = useNeutrixComputed(store => {
const firstName = store.get('user.firstName');
const lastName = store.get('user.lastName');
return `${firstName} ${lastName}`;
});
Async actions
// 1. define in the initial state
const useStore = createNeutrixStore({
count: 0,
increment: async (state) => {
await someAsyncOperation();
return { count: state.count + 1 };
}
});
// 2. use useNeutrixAction hook
import { useNeutrixAction } from 'neutrix';
const { loading, error, execute } = useNeutrixAction(
async (store) => {
await someAsyncOperation();
store.set('count', store.get('count') + 1);
}
);
Middleware
Middleware lets you intercept and transform state operations:
useStore.store.use({
onSet: (path, value, prevValue) => {
console.log(`Set: ${path} from ${prevValue} to ${value}`);
return value;
},
onGet: (path, value) => {
console.log(`Get: ${path} -> ${value}`);
return value;
},
onError: (error) => {
console.error('Store error:', error);
}
});
Suspense Support
Handle async data loading with React Suspense:
Features:
- Cache promise results
- Automatic promise tracking
Store patterns
1. Single store (no provider)
import { createNeutrixStore } from 'neutrix';
// simplest approach
const useStore = createNeutrixStore({ count: 0 });
function Counter() {
const count = useStore(s => s.count);
return <div>{count}</div>;
}
2. Single store (with provider)
import { createNeutrixStore } from 'neutrix';
const { Provider, useStore } = createNeutrixStore(
{ count: 0 },
{ provider: true }
);
function App() {
return (
<Provider>
<Counter />
</Provider>
);
}
3. Multiple stores
import { createNeutrixStore, NeutrixProvider } from 'neutrix';
const { store: userStore } = createNeutrixStore({ user: null }, { provider: true });
const { store: cartStore } = createNeutrixStore({ items: [] }, { provider: true });
function App() {
return (
<NeutrixProvider stores={{ userStore, cartStore }}>
<YourApp />
</NeutrixProvider>
);
}
Advanced features
Batch Updates
Optimize performance by batching multiple updates:
useStore.store.batch([
['user.name', 'John'],
['user.lastLogin', Date.now()],
['user.status', 'active']
]);
Dependency Tracking
Neutrix automatically tracks which parts of the state each component uses and only re-renders when those specific parts change:
// this component will only re-render when user.firstName or user.lastName change
function UserGreeting() {
const fullName = useNeutrixComputed(store => {
return `${store.user.firstName} ${store.user.lastName}`;
});
return <h1>Hello, {fullName}!</h1>;
}
Technical Details
The library provides these core types:
- Store
<T>
: Main store interface - State: Base state type
- Middleware: Middleware interface
- StoreOptions: Store configuration
- BatchUpdate: Batch update type
Type references
interface StoreOptions {
name?: string;
devTools?: boolean;
persist?: boolean | ((state: any) => any);
validate?: (state: State) => boolean | string;
migration?: {
version: number;
migrate: (oldState: any) => any;
};
concurrenct?: boolean; // <--- updated to match code
onDestroy?: () => void;
}
Next Steps
- Check out the Tutorials section for more usage patterns
- Read the API Reference