Article illustration 1

State management complexity often grows exponentially with application scale. While React's built-in hooks suffice for simple cases, larger applications typically demand more structure—leading many teams toward heavyweight solutions that introduce their own learning curves. Enter @ibnlanre/portal, a novel library designed to balance flexibility and rigor. It provides a type-safe, intuitive API that works equally well for primitive values and nested objects, all while leveraging TypeScript’s full potential.

Why Portal Stands Out

Portal distinguishes itself through several core principles:

  • Dual Store Types: Automatically infers whether state is primitive (string, number, boolean) or composite (nested objects), with each property becoming its own subscribable store.
  • Reactivity with Immutability: All updates trigger new state snapshots, ensuring predictable behavior while efficiently notifying subscribers.
  • Zero-Boilerplate React Integration: The $use hook connects components to stores with the same ergonomics as useState, but with built-in memoization and dependency tracking.
  • Actions as First-Class Citizens: Define state-mutating functions directly within stores, co-locating logic with data. These can even leverage React hooks internally for side effects.
// Example: Store with async action
const userStore = createStore({
  data: null,
  loading: false,
  async fetchUser(id) {
    this.loading.$set(true);
    const user = await fetch(`/users/${id}`).then(r => r.json());
    this.data.$set(user);
    this.loading.$set(false);
  }
});

Advanced Capabilities

Context-Aware Stores

createContextStore solves the initialization problem for stores relying on runtime data (like props or environment variables). It creates a React Context provider that dynamically builds stores:

const [UserProvider, useUserStore] = createContextStore(({ userId }) => {
  return createStore({ id: userId, preferences: {} });
});
// Usage: <UserProvider value={{ userId: '123' }}>

State Persistence Made Simple

Portal includes adapters for localStorage, sessionStorage, and cookies—complete with signing for security:

const [getStored, setStored] = createCookieStorageAdapter('prefs', {
  secret: 'my-secret',
  maxAge: 86400
});
const store = createStore(getStored() || initialState);
store.$act(setStored); // Auto-persists on change

Deep Performance Optimizations

  • Selective Reactivity: Components only re-render when specifically subscribed properties change.
  • useSync Hook: Memoizes computed values using deep dependency checks, avoiding wasteful recalculations.
  • Batched Updates: Modify multiple properties in one $set call to minimize re-renders.

When to Reach for Portal

This library shines for teams that:
1. Value TypeScript integration for autocompletion and validation.
2. Need consistent state patterns across small components and large apps.
3. Require flexible persistence (cookies, localStorage, or custom backends).
4. Prefer colocating logic with state via actions instead of scattering reducers.

The Verdict

Portal isn’t yet another state management overhaul. Instead, it thoughtfully layers enhanced capabilities atop familiar patterns. By treating stores as living entities—whether primitive values or composite structures—it eliminates the friction of context providers, reducer boilerplate, and external caching libraries. For React developers seeking a single tool that scales from widgets to enterprise applications, Portal offers a compelling blend of simplicity, safety, and power.