react-screen-flow

Getting Started

react-screen-flow is a small, typed workflow engine for React apps that move through named screens: onboarding, checkout, signup, profile completion, permission gates, and router-backed flows.

The library keeps flow rules in one place. Your app owns the real state; react-screen-flow decides which screen is active, whether navigation is allowed, and how async guards feel in the UI.

Installation

pnpm add @hbarkallah/react-screen-flow

This package expects React to be provided by your app.

Basic Usage

import { useScreenFlow, type FlowDefinition } from "@hbarkallah/react-screen-flow";

type AppState = {
  user: { name: string } | null;
  profileCompleted: boolean;
};

function LoginScreen() {
  return <h2>Login</h2>;
}

function DashboardScreen() {
  return <h2>Dashboard</h2>;
}

function CheckoutScreen() {
  return <h2>Checkout</h2>;
}

const screens = {
  login: LoginScreen,
  dashboard: DashboardScreen,
  checkout: CheckoutScreen,
};

const flow: FlowDefinition<AppState, typeof screens> = {
  screens,
  loadingStrategy: "deferred",
  resolveStart: (state) => {
    if (!state.user) return "login";
    if (!state.profileCompleted) return "dashboard";
    return "checkout";
  },
  transitions: {
    login: {
      next: "dashboard",
      canGoNext: (state) => Boolean(state.user),
    },
    dashboard: {
      prev: "login",
      next: "checkout",
      canGoNext: (state) =>
        state.profileCompleted
          ? true
          : {
              allowed: false,
              message: "Complete your profile first.",
            },
    },
    checkout: {
      prev: "dashboard",
    },
  },
};

export function FlowView({ state }: { state: AppState }) {
  const flowState = useScreenFlow(flow, state, {
    autoNavigate: true,
  });

  const ScreenComponent = flowState.ScreenComponent;

  return (
    <main>
      {flowState.isTransitioning ? <p>Checking...</p> : null}

      <ScreenComponent />

      {flowState.lastBlocked ? <p>{flowState.lastBlocked}</p> : null}

      <button onClick={() => void flowState.goPrev()} disabled={!flowState.canGoPrev}>
        Back
      </button>
      <button onClick={() => void flowState.goNext()} disabled={!flowState.canGoNext}>
        Next
      </button>
    </main>
  );
}

Why Not Existing Tools?

API Surface

import {
  createFlowEngine,
  useScreenFlow,
  applyTransitionResult,
  resolveFlowLoadingStrategy,
} from "@hbarkallah/react-screen-flow";

import type {
  FlowDefinition,
  FlowEngine,
  LoadingStrategy,
  TransitionResult,
  GuardDecision,
  ScreenIdOf,
} from "@hbarkallah/react-screen-flow";

Most React apps should use useScreenFlow. createFlowEngine evaluates flows outside React or in tests. For router-backed flows, add a small route sync helper in your app — see the React Router guide.

For deeper internals, see the Flow Engine and Runtime reference pages.

npm package: `@hbarkallah/react-screen-flow`. Install: `pnpm add @hbarkallah/react-screen-flow`. Documentation index: https://hanios123.github.io/react-screen-flow/llms.txt