Awesome Open Source
Awesome Open Source




A tiny (~250 byte) utility to create state machine components using two pure functions.

🔥 JSFiddle Demo


This project uses node and npm. Go check them out if you don't have them locally installed.

npm install --save state-machine-component

Then with a module bundler like webpack or rollup, use as you would anything else:

import stateMachine from 'state-machine-component';

The UMD build is also available on unpkg:

<script src="//"></script>

The library will install itself globally as window.stateMachineComponent.


The API is a single function that accepts 2 pure functions as arguments:

stateMachineComponent(reduce, render)

The first function, reduce(), takes in the current state and applies an action to it, similar to a reducer in Redux:

// Reduce is a redux-style reducer
function reduce(state, action) {
	// actions are like Redux Standard Actions:
	let { type, data, props } = action

	return { }  // just return the new state

The second function, render(), is a pure functional component that gets passed the current state instead of props, and a second argument action() - a function that creates a bound dispatcher for the given action type:

// Render is a functional component with little twist
function render(state, action) {
	// action() creates a dispatcher for an action type:
	return <button onClick={ action('TYPE') } />

Simple Example: Counter

// Remember:
//  `state` is the current state.
//  `action` is a redux standard action.
function reduce(state, action) {
	switch (action.type) {
		case '@@INIT': return { count: 0 }
		case 'ADD': return { count: state.count+1 }

function render(state, action) {
	return (
		<div class="counter">
			Current count: {state.count}
			<button onClick={action('ADD')}>Add 1</button>

stateMachineComponent(reduce, render)

Full Example: To-Do List

const ToDos = stateMachineComponent(
	// (state, action)
	({ todos, text }, { type, data, props }) => {
		switch (type) {
			case '@@INIT':return { todos: props.todos || [], text: '' };
			case 'ADD': return { todos: todos.concat(text), text: '' };
			case 'TEXT': return { text: };
	// state, action(type)
	({ todos, text }, action) => (
			<h2>State Machine ToDos</h2>
			<ul>{ todo => <li>{todo}</li> )}</ul>
			<form onSubmit={action('ADD')}>
				<input value={text} onInput={action('TEXT')} />


MIT License © Jason Miller

Get A Weekly Email With Trending Projects For These Topics
No Spam. Unsubscribe easily at any time.
javascript (69,803
state-management (191
preact (143
state-machine (107