Skip to content

Introduction

React owns your components. Nobody owns your objects. This page explains the gap, what remodulo does about it, and when you don't need it.

The problem

A long-lived React app is full of objects that are not UI. A socket for the screen on display. A poller. A per-route cache. A draft the user has not saved.

React has no slot for them. So they end up smeared across three places:

  • useEffect - the object's life is tied to a render. A remount and a StrictMode double-invoke both re-run it, and neither is distinguishable from inside the effect.
  • A singleton - created at startup, disposed never. The orders store still polls for a screen nobody has open.
  • A context - passes the object down, but creates and destroys nothing. Someone else still owns it - usually one of the two above.

What remodulo is

An ownership layer. State-agnostic, and small.

  • Explicit ownership - A module is a scoped set of providers with a lifecycle. It opens where an area of your app opens - a route, a dialog, a panel - and closes with it. The services declared in it are created there, live there, and die there.

  • Scoped Dependency Injection - Resolution walks up the tree. A service asks for a dependency by token; the nearest module above that declares it answers. Nothing is passed down by hand.

  • Deterministic LIFO/RAII lifecycle - Whatever a module created, it destroys - children before parents, last-created first. A throwing disposer does not strand the rest.

Each module owns its dependency graph, lifecycle, and resources. When the UI subtree disappears, everything it owns disappears with it.

<AppProvider>
└── <App>

    ├── <AuthModule>
    │      ├── AuthService
    │      ├── SessionStore
    │      └── TokenCache

    └── <ChatModule>
           ├── ChatService
           ├── ChatStore
           └── MessageApi

Remodulo is not

A state manager, a routing library, or a data fetching library.

Remodulo manages ownership. Your state management, rendering, and data fetching remain entirely your choice - see Connecting Reactivity.

The packages

PackageWhat it is
@remodulo/containerThe DI kernel. Zero dependencies, works without React.
@remodulo/reactModules, boundaries, the lifecycle, the props bridge.

@remodulo/container + @remodulo/react together cost ~9 kB gzip.

Who it is for

Apps that stay open. Dashboards, editors, back offices - anything with connections to keep, caches to scope, and screens that come and go for hours.

When not to bother: a small app with no long-lived services. If nothing outlives a component and nothing leaks, useEffect is enough - remodulo would be ceremony.

Where to go next

Guides

MIT licensed.