Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
M

microstates

> 编程语言
Open source

Composable state primitives for JavaScript

1.3K stars0 likes1 views
WebsiteGitHub

About

Composable state primitives for JavaScript

Microstates

Microstates makes working with pure functions over immutable data feel like working with the classic, mutable models we all know and love.

Table of Contents

  • Features

  • Why Microstates?

    • M in MVC
    • Functional Models
  • What is a Microstate?

  • Types and Type Composition

    • Creating your own microstates
    • Array Microstates
    • Object Microstates
  • Transitions

    • Transitions for built-in types
    • Type transitions
    • Chaining transitions
    • The initialize transition
    • The set transition
    • Transition scope
  • State Machines

    • Explicit Transitions
    • Transition methods
    • Immutable Object vs Immutable Data Structure
  • Framework Integrations

  • microstates npm package

    • create(Type, value): Microstate
    • from(any): Microstate
    • map(microstate, fn): Microstate
  • Streaming State

    • Structural Sharing
    • Memoized Getters
    • Debounce no-op transitions
    • Identity Constructors
      • Store(microstate, callback)
      • Observable.from(microstate)
  • The Vision of Microstates

    • Shared Solutions
    • Added Flexibility
    • Framework Agnostic Solutions
  • FAQ

    • What if I can't use class syntax?
    • What if I can't use Class Properties?
  • Run Tests

    Videos

    • Building a shopping cart with Microstates.js - The Frontside YouTube - Taras Mankovski & Alex Regan
    • State of Enjoyment at Framework Summit 2018 - Charles Lowell
    • Microstates: The Ember component of state management at EmberATX
    • Composable State Primitives for JavaScript with Charles Lowell & Taras Mankovski - Devchat.tv
    • Composable State Management with Microstates.js at Toronto.js - Taras Mankovski

    Chat

    Join our community on Discord. Everyone is welcome. If you're a new to programming join our #beginner channel where extra care is taken to support those who're just getting started.

Features

With Microstates added to your project, you get:

  • Composable type system
  • Reusable state atoms
  • Pure immutable state transitions without writing reducers
  • ⚡️ Lazy and synchronous out of the box
  • Most elegant way to express state machines
  • Transpilation free type system
  • Optional integration with Observables
  • ⚛ Use in Node.js, browser or React Native
  • It's tiny

But, most importantly, Microstates makes working with state fun.

When was the last time you had fun working with state?

For many, the answer is probably never, because state management in JavaScript is an endless game of compromises. You can choose to go fully immutable and write endless reducers. You can go mutable and everything becomes an observable. Or you can setState and lose the benefits of serialization and time travel debugging.

Unlike the view layer, where most frameworks agree on some variation of React's concept of components, none of the current crop of state management tools strike the same balance that React components introduced to the API.

React components have a tiny API. They are functional, simple and extremely reusable. The tiny API gives you high productivity for little necessary knowledge. Functional components are predictable and easy to reason about. They are conceptually simple, but simplicity hides an underlying architecture geared for performance. Their simplicity, predictability and isolation makes them composable and reusable.

These factors combined are what make React style components easy to work with and ultimately fun to write. A Tiny API abstracting a sophisticated architecture that delivers performance and is equally useful on small and big projects is the outcome that we set out to achieve for state management with Microstates.

It's not easy to find the right balance between simplicity and power, but considering the importance of state management in web applications, we believe it's a worthy challenge. Checkout the Vision of Microstates section if you're interested in learning more about where we're going.

What is a Microstate?

A Microstate is just an object that is created from a value and a type. The value is just data, and the type is what defines how you can transition that data from one form into the next. Unlike normal JavaScript objects, microstates are 100% immutable and cannot be changed. They can only derive new immutable microstates through one of their type's transitions.

Types and Type Composition

Microstates comes out of the box with 5 primitive types: Boolean, Number, String, Object and Array.

javascript
import { create, valueOf } from 'microstates';

let meaningOfLifeAndEverything = create(Number, 42);
console.log(meaningOfLifeAndEverything.state);
//> 42

let greeting = create(String, 'Hello World');
console.log(greeting.state);
//> Hello World

let isOpen = create(Boolean, true);
console.log(isOpen.state);
//> true

// For Object and Array use microstates valueOf method
let foo = create(Object, { foo: 'bar' });
console.log(valueOf(foo));
//> { foo: 'bar' }

let numbers = create(Array, [1, 2, 3, 4]);
console.log(valueOf(numbers));
//> [ 1, 2, 3, 4 ]

Apart from these basic types, every other type in Microstates is built by combining other types. So for example, to create a Person type you could define a JavaScript class with two properties: name which has type String and age which has type Number.

javascript
class Person {
  name = String;
  age = Number;
}

Once you have a type, you can use that type to create as many people as your application requires:

javascript
import { create } from 'microstates';

let person = create(Person, { name: 'Homer', age: 39 });

Every microstate created with a type of Person will be an object extending Person to have a set() method:

…

For the five built in types, Microstates automatically gives you transitions that you can use to change their value. You don't have to write any code to handle common operations.

Creating your own microstates

Types can be combined with other types freely and Microstates will take care of handling the transitions for you. This makes it possible to build complex data structures that accurately describe your domain.

Let's define another type that uses the person type.

javascript
class Car {
  designer = Person;
  name = String;
}

let theHomerCar = create(Car, {
  designer: { name: 'Homer', age: 39 },
  name: 'The Homer'
});

theHomerCar object will have the following shape,

…

You can use the object dot notation to access sub microstates. Using the same example from above:

javascript
theHomerCar.designer;
//> Microstate{ name: Microstate'Homer', age: Microstate39 }

theHomerCar.designer.age.state;
//> 39

theHomerCar.name.state;
//> The Homer

You can use the valueOf() function available from the microstates module to retrieve the underlying value represented by a microstate.

javascript
import { valueOf } from 'microstates';

valueOf(theHomerCar);
//> { designer: { name: 'Homer', age: 39 }, name: 'The Homer' }

Array Microstates

Quite often it is helpful to describe your data as a collection of types. For example, a blog might have an array of posts. To do this, you can use the array of type notation [Post]. This signals that Microstates of this type represent an array whose members are each of the Post type.

javascript
class Blog {
  posts = [Post];
}

class Post {
  id = Number;
  title = String;
}

let blog = create(Blog, {
  posts: [
    { id: 1, title: 'Hello World' },
    { id: 2, title: 'Most fascinating blog in the world' }
  ]
});

for (let post of blog.posts) {
  console.log(post);
}
//> Microstate{ id: 1, title: 'Hello World' }
//> Microstate{ id: 2, title: 'Most fascinating blog in the world' }

When you're working with an array microstate, the shape of the Microstate is determined by the value. In this case, posts is created with two items which will, in turn, create a Microstate with two items. Each item will be a Microstate of type Post. If you push another item onto the posts Microstate, it'll be treated as a Post.

javascript
let blog2 = blog.posts.push({ id: 3, title: 'It is only getter better' });

for (let post of blog2.posts) {
  console.log(post);
}

//> Microstate{ id: 1, title: 'Hello World' }
//> Microstate{ id: 2, title: 'Most fascinating blog in the world' }
//> Microstate{ id: 3, title: 'It is only getter better' }

Notice how we didn't have to do any extra work to define the state transition of adding another post to the list? That's the power of composition!

Object Microstates

You can also create an object microstate with {Post}. The difference is that the collection is treated as an object. This can be helpful when creating normalized data stores.

javascript
class Blog {
  posts = { Post };
}

class Post {
  id = Number;
  title = String;
}

let blog = create(Blog, {
  posts: {
    '1': { id: 1, title: 'Hello World' },
    '2': { id: 2, title: 'Most fascinating blog in the world' }
  }
});

blog.posts.entries['1'];
//> Microstate{ id: 1, title: 'Hello World' }

blog.posts.entries['2'];
//> Microstate{ id: 2, title: 'Most fascinating blog in the world' }

Object type microstates have Object transitions, such as assign, put and delete.

javascript
let blog2 = blog.posts.put('3', { id: 3, title: 'It is only getter better' });

blog2.posts.entries['3'];
//> Microstate{ id: 3, title: 'It is only getter better' }

Transitions

Transitions are the operations that let you derive a new state from an existing state. All transitions return another Microstate. You can use state charts to visualize microstates. For example, the Boolean type can be described with the following statechart.

The Boolean type has a toggle transition which takes no arguments and creates a new microstate with the state that is opposite of the current state.

Here is what this looks like with Microstates.

javascript
import { create } from 'microstates';

let bool = create(Boolean, false);

bool.state;
//> false

let inverse = bool.toggle();

inverse.state;
//> true

Pro tip Remember, Microstate transitions always return a Microstate. This is true both inside and outside the transition function. Using this convention can allow composition to reach crazy levels of complexity.

Let's use a Boolean in another type and see what happens.

javascript
class App {
  name = String;
  notification = Modal;
}

class Modal {
  text = String;
  isOpen = Boolean;
}

let app = create(App, {
  name: 'Welcome to your app',
  notification: {
    text: 'Hello there',
    isOpen: false
  }
});

let opened = app.notification.isOpen.toggle();
//> Microstate

valueOf(opened);
//> {
// name: 'Welcome to your app',
// notification: {
//   text: 'Hel

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

JavaScriptbatch-transitionscompositionlensmicrostates

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言