@mobx-state-machine-router/core
v6.0.0
Published
State Machine routing for MobX
Maintainers
Readme
@mobx-state-machine-router/core
Declarative, predictable routing powered by finite state machines and MobX
Why?
- State Machine First — Define valid states and transitions. Invalid navigation is impossible by design.
- MobX Powered — Reactive state updates with fine-grained re-rendering.
- Type Safe — Full TypeScript support with inferred types.
- Lightweight — ~3KB gzipped, zero dependencies (MobX is a peer dependency).
- React Native Ready — Works without URLs out of the box.
Installation
npm install @mobx-state-machine-router/core mobxQuick Start
import MobxStateMachineRouter, { TStates } from '@mobx-state-machine-router/core';
// 1. Define states and actions as string literal types
type State = 'home' | 'products' | 'product-detail';
type Action = 'go-products' | 'view-product' | 'go-home';
type Params = {
productId?: string;
};
// 2. Define the state machine
const states: TStates<State, Action> = {
home: {
actions: { 'go-products': 'products' },
},
products: {
actions: {
'go-home': 'home',
'view-product': 'product-detail',
},
},
'product-detail': {
actions: {
'go-home': 'home',
'go-products': 'products',
},
},
};
// 3. Create the router
const router = MobxStateMachineRouter<State, Params, Action>({
states,
currentState: { name: 'home', params: {} },
});
// 4. Navigate
router.emit('go-products');
console.log(router.currentState.name); // 'products'
router.emit('view-product', { productId: '123' });
console.log(router.currentState.params); // { productId: '123' }Usage with React
import { observer } from 'mobx-react-lite';
import { router } from './router';
const App = observer(() => {
const { name, params } = router.currentState;
return (
<div>
<nav>
<button onClick={() => router.emit('go-home')}>Home</button>
<button onClick={() => router.emit('go-products')}>Products</button>
</nav>
{name === 'home' && <HomePage />}
{name === 'products' && <ProductsPage />}
{name === 'product-detail' && <ProductDetail id={params.productId} />}
</div>
);
});API
MobxStateMachineRouter(options)
Creates a router instance.
| Option | Type | Description |
|--------|------|-------------|
| states | TStates<S, A> | State machine definition |
| currentState | { name: S, params: P } | Initial state (optional) |
| persistence | IPersistence | URL persistence layer (optional) |
router.currentState
Observable object containing current state:
router.currentState.name // Current state name
router.currentState.params // Current params objectrouter.emit(action, params?)
Emit an action to transition states:
router.emit('go-home');
router.emit('view-product', { productId: '123' });router.destroy()
Clean up subscriptions (important when using persistence).
observeParam(router, property, paramName, callback)
Observe a specific param for changes:
import { observeParam } from '@mobx-state-machine-router/core';
observeParam(router, 'currentState', 'productId', (change) => {
console.log('productId changed:', change.newValue);
});Observing & Intercepting
import { observe, intercept } from 'mobx';
// Observe state changes
observe(router, 'currentState', ({ newValue }) => {
console.log('Navigated to:', newValue.name);
});
// Intercept and guard navigation
intercept(router, 'currentState', (change) => {
if (change.newValue.name === 'admin' && !isLoggedIn) {
return { ...change, newValue: { name: 'login', params: {} } };
}
return change;
});URL Persistence
For URL synchronization, install the companion package:
npm install @mobx-state-machine-router/url-persistence historySee @mobx-state-machine-router/url-persistence for details.
Compatibility
- MobX 4.x, 5.x, or 6.x
- React 16.8+ (for hooks) or React Native
- TypeScript 4.x or 5.x (optional)
License
MIT © Anzor Bashkhaz
