Expressive MVC
Define reactive UI with plain classes. When properties change, your components will too.
Documentation · Playground · Discord
Expressive puts application state, behavior, and lifecycle in plain classes. Class fields are reactive, getters are computed, methods are auto-bound, and UI components subscribe only to the values they read.
Install
npm install @expressive/react
Quick start
import State from '@expressive/react';
class Counter extends State {
count = 0;
increment() {
this.count++;
}
decrement() {
this.count--;
}
}
function CounterWidget() {
const { count, increment, decrement } = Counter.use();
return (
<div>
<button onClick={decrement}>-</button>
<span>{count}</span>
<button onClick={increment}>+</button>
</div>
);
}
No reducers, selectors, dependency arrays, or action wrappers. Update a property and every consumer that reads it updates automatically.
The adapter is renderer-agnostic, so the same install covers React Native and Expo - exercised on an iOS simulator and an Android emulator in both Debug and Release builds (Expo SDK 57, React Native 0.86) and gated per release on Metro resolution and a Hermes build. See React Native for the three boundaries.
Continue with Getting Started, explore the guides, or browse the API reference.
Packages
| Package | Description |
| --- | --- |
| @expressive/mvc | Framework-agnostic reactive core and component model. Comes with the adapter - install directly only for host-agnostic code. |
| @expressive/react | React adapter and the recommended entry point for React applications. The only package a React app installs. |
| @expressive/router | Host-agnostic router built on Expressive components. The newest package, and the one that moves the most. |
All packages are pre-1.0 under one discipline: breaking changes land only in minor versions, each documented by a changeset in the package's CHANGELOG - patch releases are always safe to take.
Learn more
- Why classes?
- Design decisions
- Migrating from hooks
- Comparisons with other state libraries
- Live examples
- Using Expressive with a coding agent
Contributing
This repository is a Bun workspace. To get started:
bun install
bun run test
bun run build
See AGENTS.md for repository conventions and .github/RELEASING.md for the release process.