Skip to content

Wirestate

docsnpmlicense

Wirestate is a TypeScript state-management toolkit built around dependency-injected services.

Application logic lives in @Injectable classes. React and Lit adapters provide those services to UI trees. Reactivity is separate: use MobX, Preact Signals, plain values, or another reactivity adapter inside your services.

Use Wirestate when you want service-owned state and workflows that can be scoped to an app, subtree, feature, modal, tenant, or test.

Packages

PackagePurpose
@wirestate/coreContainers, injectable services, lifecycle, messaging.
@wirestate/reactReact provider, injection hooks, and component-owned handlers.
@wirestate/litLit providers, decorators, controllers, and element handlers.
@wirestate/mobxFramework-agnostic MobX exports for shared services.
@wirestate/react-mobxMobX React reactivity binding (mobx-react-lite).
@wirestate/lit-mobxMobX Lit reactivity binding (@adobe/lit-mobx).
@wirestate/signalsFramework-agnostic Preact Signals exports for shared services.
@wirestate/react-signalsPreact Signals React reactivity binding.
@wirestate/lit-signalsPreact Signals Lit reactivity binding (@lit-labs/preact-signals).
wirestateReact-oriented compatibility package for the unscoped package name.

Install

Install the Wirestate packages for the stack you use.

bash
# React + Signals
npm install @wirestate/core @wirestate/signals @wirestate/react @wirestate/react-signals

# React + MobX
npm install @wirestate/core @wirestate/mobx @wirestate/react @wirestate/react-mobx

# Lit + Signals
npm install @wirestate/core @wirestate/signals @wirestate/lit @wirestate/lit-signals

# Lit + MobX
npm install @wirestate/core @wirestate/mobx @wirestate/lit @wirestate/lit-mobx

Wirestate decorators work with legacy TypeScript decorators and TC39 standard decorators. For legacy TypeScript decorators, enable experimentalDecorators.

json
{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

Example

tsx
import { Injectable } from "@wirestate/core";
import { makeAutoObservable } from "@wirestate/mobx";
import { ContainerProvider, useInjection } from "@wirestate/react";
import { observer } from "@wirestate/react-mobx";

@Injectable()
class CounterService {
  public count: number = 0;

  public constructor() {
    makeAutoObservable(this);
  }

  public increment(): void {
    this.count += 1;
  }
}

const Counter = observer(function Counter() {
  const counter = useInjection(CounterService);

  return <button onClick={() => counter.increment()}>Count: {counter.count}</button>;
});

export function Application() {
  return (
    <ContainerProvider config={{ bindings: [CounterService] }}>
      <Counter />
    </ContainerProvider>
  );
}

@wirestate/react connects the component to the service. observer subscribes Counter to the MobX observables it reads during render. The same service pattern can use MobX or Preact Signals in React or Lit.

Documentation

Development

bash
pnpm install
pnpm lint
pnpm typecheck
pnpm test
pnpm build
pnpm docs:build

Build output goes to target/.

License

MIT