# TimeWarp.State puts a reducer pipeline inside Blazor components

> TimeWarp.State, formerly Blazor-State, is a fully asynchronous state management library for Blazor and console hosts in which reducers and effects are handled by the same async handlers running through a MediatR style pipeline. It suits teams that want one state model across UI and background hosts, and it is currently shipping as a 12.0 beta.

**TimeWarpEngineering/timewarp-state** — A Blazor State management library by TimeWarp.

- Repository: https://github.com/TimeWarpEngineering/timewarp-state
- Stars: 610 · Forks: 57
- Language: C#
- License: Unlicense
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/timewarpengineering-timewarp-state

## The core package has no Blazor dependency at all

The first design decision is that TimeWarp.State, previously known as Blazor-State, is a fully asynchronous state management library whose core package has no Blazor dependency, so console and other non-UI hosts can dispatch actions through the same store. Blazor components, JavaScript interop and render subscriptions live in a separate package, TimeWarp.State.Blazor. The library handles both Reducers and Effects consistently using async Handlers, which is the part that distinguishes it from a component-scoped state library. A reducer is a pure transition, an effect is a side effect, and treating both with the same async handler shape means a side effect is expressed in the same vocabulary as a state change. The samples directory makes the console case concrete, with a console sample that dispatches an action without Blazor at all, and the published documentation is at timewarpengineering.github.io/timewarp-state with a step by step guide in the state and action handler sample.

## The mediator pipeline is where cross-cutting behaviour goes

By utilizing the TimeWarp.Mediator pipeline, TimeWarp.State enables a flexible, middleware-driven architecture for managing state, similar to the request-processing pipeline in ASP.NET. The stated benefit is that this approach allows developers to inject custom behaviors such as logging, validation and caching directly into the state management flow. That is a real architectural choice rather than a convenience. In a component-based library, a cross-cutting concern like logging every state transition has to be bolted on, and it ends up either duplicated in every component or hidden inside the library. Here the pipeline is the path every action takes, so a logging or validation behaviour is one registration rather than a convention every team has to remember. The one thing to be careful about is the dependency, because the hosts consume TimeWarp.Mediator 14-beta via generated AddGeneratedMediator<ClientPipeline>() and named pipelines, and the documentation is explicit that this is not MediatR and not the reflection based AddMediator() registration. Getting that wrong means your pipeline is not the one the library was written against.

## Four packages, each adding one capability

The package set is layered, and the README is clear about what belongs where. The core TimeWarp.State carries the store and the pipeline. TimeWarp.State.Blazor adds components, JavaScript interop and render subscriptions. TimeWarp.State.Plus adds routing, persistence and action tracking, and it depends on TimeWarp.State.Blazor, with the package id deliberately unchanged despite the move. TimeWarp.State.Telemetry adds OpenTelemetry action spans for the Aspire dashboard or any OTel backend, and on top of those spans sits TimeWarp DevTools, a development-only Blazor inspector registered with AddTimeWarpStateDevTools(). The DevTools is described as the action log, the state tree and the diff, and it is explicitly not a production dependency. The samples show each capability in isolation, with separate directories for action tracking, routing, telemetry, persistence, render control, console use and notifications, which is a good way to learn the library one feature at a time.

## Installing is four package references and two host registrations

The installation section lists the four NuGet references:

```console
dotnet add package TimeWarp.State
dotnet add package TimeWarp.State.Blazor
dotnet add package TimeWarp.State.Plus
dotnet add package TimeWarp.State.Telemetry
```

The registration step is where the Blazor and console split shows up in code. Blazor hosts call AddTimeWarpState and AddTimeWarpStateBlazor, and console hosts call AddTimeWarpState only. The README points at a migration document for version 12.0.0-beta.10, which tells you that the registration surface has been moving. The packages themselves are published on NuGet under the TimeWarp.State names, with a NuGet profile page for TimeWarp Enterprises, and the badge in the readme shows the .NET 11.0 target. The licensing is worth noting before you build on it, because the repository ships an unlicense.txt, meaning the code is released into the public domain, which is unusual for a commercial-looking package set and removes most of the questions a legal team would ask about adoption.

## JavaScript dispatch is opt-in, and every action must be allowed by name

JavaScript can dispatch actions with timeWarpState.DispatchRequest(name, request), and the security model is the interesting part. The feature is opt-in, in the sense that you allow each action explicitly and everything else is rejected. The registration is a single call:

```csharp
builder.Services.AddJavaScriptDispatch(b => b.Allow<CounterState.IncrementCountActionSet.Action>());
```

So a page script cannot reach arbitrary state transitions, it can only reach the actions whose types you have listed. That matters because a state management library that exposes a generic dispatch to the browser is a command injection surface, and this one does not have it. The alternative to this route is to keep dispatch inside C# and let the browser send user intent rather than commands, which is the pattern the rest of the library leans toward, with the opt-in dispatch there for the cases where the browser genuinely needs to trigger something.

## The action catalog turns state transitions into a runtime inventory

A newer feature is the action catalog, and it addresses something that usually gets bolted on later. Marking a user-facing action with the CatalogAction attribute lets you enumerate and execute those actions at runtime, for example from a Ctrl-K command palette or as agent tools. The attribute carries a description and a permission list, as in the passkey example where the action is described as adding a passkey to the signed-in account and the required permission is credentials.write. Two things follow from putting the metadata on the action itself. The catalog is derived from the code rather than maintained separately, so an action that is not marked is simply not in the inventory. And the permission list travels with the action, so a command palette or an agent tool has a machine-readable statement of what the action is allowed to touch, rather than a list that lives somewhere else and drifts. The repository layout shows the direction of travel here, with skills/, kanban/, analysis/, ai-context.md, an .ai/ directory and a claude.md file, which reads like a project that is being developed with coding assistants in the loop.

## Rendering is controlled, not automatic

Blazor applications re-render when state changes, and in a state library that coupling is worth being deliberate about. The render control sample shows ShouldRender, parameter checks and RegisterRenderTrigger, which is the mechanism for deciding when a component should react. This is the part of the design that a team adopting a state library tends to underappreciate, because with a reducer model you can end up re-rendering the whole tree on every action if nothing narrows the scope. The library also has an action tracking feature, listed under TimeWarp.State.Plus, and a notifications sample, so the set of concerns the framework has taken on goes beyond reducers to the questions around what changed and who needs to know. The naming for this package set, TimeWarp.State, plus the earlier Blazor-State name, suggests the project is being repositioned from a Blazor component library into a general state management library for the .NET ecosystem, and the console-first core package is the clearest signal of that.

## Where TimeWarp.State is the wrong choice

Three situations argue against it. The first is a Blazor application with a handful of components and little shared state, because the store, the pipeline and the generated mediator registration are all infrastructure you would be adopting to manage three properties. The second is a team that already standardised on a state management approach, since the library's value is that everything routes through one pipeline, and mixing it with another pattern means two ways to change state in the same application. The third is a project with a hard stability requirement, because the current line is a prerelease. The three most recent tags are v12.0.0-beta.15, v12.0.0-beta.14 and v12.0.0-beta.13, all published in the second half of October 2026, and the README itself points at a migration document for beta.10, which tells you the registration surface is still moving. That is fine for a team that wants to shape a library alongside its author, and awkward for a team that wants a package it can pin and forget. The realistic alternative for the stable case is to keep state in the components and use the Blazor built-in mechanisms, or to adopt a general purpose store that is already past its beta phase, accepting that you lose the reducer and effect symmetry and the middleware pipeline that are the reason to choose this library at all.

## Conclusion

Adopt TimeWarp.State when you have a Blazor application whose state transitions deserve testing independent of the UI, and when you also run console or service hosts that need to dispatch the same actions. Skip it if your components hold little shared state, since the indirection costs more than it saves there. Verify first which prerelease you are pinning, because the current line is 12.0.0 beta, and note that the host must use the generated mediator registration rather than the reflection based one, otherwise the pipeline the library depends on is not the one you think you have.

## FAQ

### What is TimeWarp.State?

It is a fully asynchronous state management library, previously known as Blazor-State. The core package has no Blazor dependency, so console and other non-UI hosts can dispatch actions through the same store, and Blazor components, JavaScript interop and render subscriptions live in TimeWarp.State.Blazor.

### How do I install TimeWarp.State?

Add the packages with dotnet add package for TimeWarp.State, and add TimeWarp.State.Blazor, TimeWarp.State.Plus and TimeWarp.State.Telemetry as needed. Blazor hosts call AddTimeWarpState and AddTimeWarpStateBlazor, while console hosts call AddTimeWarpState only.

### What does the action catalog do?

Marking a user-facing action with the CatalogAction attribute lets you enumerate and execute those actions at runtime, for example from a Ctrl-K command palette or as agent tools. The attribute carries a description and a permissions list, so the catalogue is derived from the code rather than maintained separately.

### Can JavaScript dispatch actions into TimeWarp.State?

Yes, through timeWarpState.DispatchRequest(name, request), but it is opt-in. You allow each action explicitly with AddJavaScriptDispatch, and everything else is rejected, so browser code cannot reach arbitrary state transitions.

### Is TimeWarp.State still maintained?

The repository is not archived and the last push was on 2026-10-16. The recent tags are v12.0.0-beta.15, v12.0.0-beta.14 and v12.0.0-beta.13, so the current line is a prerelease, the .NET target is 11.0, and the code is released under the Unlicense in unlicense.txt.

## Sources

- [Issues](https://github.com/TimeWarpEngineering/timewarp-state/issues)
- [License: Unlicense](https://github.com/TimeWarpEngineering/timewarp-state/blob/master/LICENSE)
- [README](https://github.com/TimeWarpEngineering/timewarp-state/blob/master/README.md)
- [Releases](https://github.com/TimeWarpEngineering/timewarp-state/releases)
- [TimeWarpEngineering/timewarp-state on GitHub](https://github.com/TimeWarpEngineering/timewarp-state)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/timewarpengineering-timewarp-state
