npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@markiearnold/flow-machine

v4.3.15

Published

A self-contained flow machine framework for React - completely unstyled for maximum flexibility

Readme

Flow Machine

Enterprise-grade conversational UI framework for React that makes building complex, multi-step user interactions simple and intuitive.

Complete Documentation | 🚀 Quick Start | 🎨 Styling Guide | 🔧 API Reference

🔗 Links

Features

  • Flow Management: Create and manage conversational flows with ease
  • Pre-built Components: Ready-to-use React components for chat interfaces
  • Templates: Pre-configured flow templates for common use cases
  • A/B Testing: Built-in A/B testing framework for flow optimization
  • Customizable UI: Flexible styling and theming options
  • Responsive Design: Mobile-friendly components that adapt to different screen sizes
  • TypeScript Support: Full TypeScript support with type definitions
  • Assistant-UI Integration: Seamless integration with assistant-ui for hybrid chat/flow experiences
  • Intent Routing: Map natural language intents to specific flows
  • Tool Registry: Shared tools between chat and flows with enhanced error handling
  • Flow Handoffs: Smart suggestions for next actions when flows complete
  • Observability: Built-in analytics and monitoring for flow execution

Installation

npm install @markiearnold/flow-machine

Quick Start

Simple Usage

import React from "react";
import {FlowUI, useFlowMachine, createFlow} from "@markiearnold/flow-machine";

function App() {
  const config = createFlow({
    flowId: "my-flow",
    startId: "welcome",
  })
    .step({
      id: "welcome",
      prompt: "Welcome! How can I help you today?",
      suggestions: [
        {label: "Get started", value: "start"},
        {label: "Learn more", value: "learn"},
        {label: "Contact support", value: "support"},
      ],
      next: (ctx) => {
        if (ctx.lastInput === "start") return "get-started";
        if (ctx.lastInput === "learn") return "learn-more";
        return "contact-support";
      },
    })
    .step({
      id: "get-started",
      prompt: "Great! Let's get you started with our platform.",
      suggestions: [
        {label: "Next step", value: "next"},
        {label: "Go back", value: "back"},
      ],
      next: (ctx) => {
        if (ctx.lastInput === "back") return "welcome";
        return null; // End flow
      },
    })
    .build();

  const machine = useFlowMachine(config);

  return (
    <FlowUI
      machine={machine}
      title="My Flow App"
      subtitle="Interactive conversation flow"
    />
  );
}

With Provider (Recommended)

import React from "react";
import {FlowUI, FlowProvider, createFlow} from "@markiearnold/flow-machine";

function App() {
  const config = createFlow({
    flowId: "my-flow",
    startId: "welcome",
  })
    .step({
      id: "welcome",
      prompt: "Welcome! How can I help you today?",
      suggestions: [
        {label: "Get started", value: "start"},
        {label: "Learn more", value: "learn"},
        {label: "Contact support", value: "support"},
      ],
      next: () => null, // End flow
    })
    .build();

  return (
    <FlowProvider config={config}>
      <FlowUI title="My Flow App" subtitle="Interactive conversation flow" />
    </FlowProvider>
  );
}

Core Components

FlowUI

The main interactive component that provides the complete flow interface.

import {FlowUI} from "@markiearnold/flow-machine";

<FlowUI
  machine={machine}
  title="My App"
  subtitle="Interactive flow"
  showProgress={true}
  theme="light"
/>;

FlowProvider

Context provider for better state management and sharing flow state across components.

import {FlowProvider, FlowUI, createFlow} from "@markiearnold/flow-machine";

function App() {
  const config = createFlow({
    flowId: "my-flow",
    startId: "welcome",
  })
    .step({
      id: "welcome",
      prompt: "Welcome! How can I help you today?",
      suggestions: [
        {label: "Get started", value: "start"},
        {label: "Learn more", value: "learn"},
        {label: "Contact support", value: "support"},
      ],
      next: () => null,
    })
    .withValidation(false) // Disable validation warnings
    .build();

  return (
    <FlowProvider config={config}>
      <FlowUI title="My Flow App" subtitle="Interactive conversation flow" />
    </FlowProvider>
  );
}

export default App;

FlowChat

A standalone chat component for displaying conversations.

import React from "react";
import {FlowChat, useFlowMachine, createFlow} from "@markiearnold/flow-machine";

function ChatApp() {
  const config = createFlow({
    flowId: "chat-flow",
    startId: "welcome",
  })
    .step({
      id: "welcome",
      prompt: "Hello! How can I help?",
      suggestions: [
        {label: "Get help", value: "help"},
        {label: "Learn more", value: "learn"},
      ],
      next: () => null,
    })
    .build();

  const machine = useFlowMachine(config);

  return <FlowChat machine={machine} />;
}

FlowInspector

Development tool for debugging flow states and transitions.

import React from "react";
import {
  FlowInspector,
  useFlowMachine,
  createFlow,
} from "@markiearnold/flow-machine";

function DebugApp() {
  const config = createFlow({
    flowId: "debug-flow",
    startId: "welcome",
  })
    .step({
      id: "welcome",
      prompt: "Hello! This is a debug flow.",
      suggestions: [{label: "Continue", value: "continue"}],
      next: () => null,
    })
    .build();

  const machine = useFlowMachine(config);

  return <FlowInspector machine={machine} />;
}

Assistant-UI Integration

Flow-machine now seamlessly integrates with assistant-ui to create powerful hybrid chat/flow experiences. This integration provides the best of both worlds: structured, deterministic flows and flexible, natural language chat.

Quick Integration

import {useAssistant} from "assistant-ui";
import {
  MessageBridge,
  createBridgeConfig,
  IntentRouter,
  ToolRegistry,
} from "@markiearnold/flow-machine";

function App() {
  // Create flow-machine configuration
  const bridgeConfig = createBridgeConfig({
    assistantId: "my-assistant",
    sessionId: "session-123",
    intentRouter: new IntentRouter({
      mappings: {
        book_appointment: {
          id: "appointment-flow",
          seed: (params) => ({
            service: params?.service,
            date: params?.date,
          }),
        },
      },
    }),
    toolRegistry: new ToolRegistry(),
  });

  const bridge = new MessageBridge(bridgeConfig);

  // Assistant-UI configuration
  const assistant = useAssistant({
    api: "/api/assistant",
    onMessage: async (message) => {
      const result = await bridge.processAssistantMessage(message);

      if (result.flowStarted) {
        return {
          role: "assistant",
          content: `Starting ${result.flowId}...`,
          suggestions: ["Get help", "Start over"],
        };
      }

      return result.response;
    },
  });

  return (
    <div>
      <assistant-ui-chat assistant={assistant} />
    </div>
  );
}

Key Features

  • Intent Routing: Map natural language intents to specific flows
  • Tool Registry: Shared tools between chat and flows with enhanced error handling
  • Flow Handoffs: Smart suggestions for next actions when flows complete
  • Chat Steps: Embed chat interfaces within flows for hybrid experiences
  • Observability: Built-in analytics and monitoring for flow execution
  • Message Bridge: Seamless communication between assistant-ui and flow-machine

Learn More

Flow Management

Creating Flows

import {createFlow, createSimpleFlow} from "@markiearnold/flow-machine";

// Simple flow (automatically generates next functions)
const simpleFlow = createSimpleFlow("simple-flow", [
  {id: "step1", prompt: "Hello!"},
  {id: "step2", prompt: "How are you?"},
]);

// Advanced flow with custom logic using fluent API
const advancedFlow = createFlow({
  flowId: "advanced-flow",
  startId: "welcome",
})
  .step({
    id: "welcome",
    prompt: "Welcome to our service!",
    suggestions: [
      {label: "Get started", value: "start"},
      {label: "Learn more", value: "learn"},
    ],
    onEnter: (context) => {
      console.log("Entered welcome step");
    },
    next: (ctx) => {
      if (ctx.lastInput === "start") return "get-started";
      if (ctx.lastInput === "learn") return "learn-more";
      return null;
    },
  })
  .step({
    id: "get-started",
    prompt: "Let's get you started!",
    next: () => null,
  })
  .build();

Flow Templates

import React from "react";
import {useTemplate, FlowUI} from "@markiearnold/flow-machine";

function OnboardingFlow() {
  // useTemplate returns the flow machine state directly
  const flowMachine = useTemplate("user-onboarding", {
    companyName: "Acme Corp",
    features: ["Feature 1", "Feature 2"],
  });

  return <FlowUI machine={flowMachine} />;
}

Disabling Validation Warnings

Flow Machine provides helpful validation warnings to help you build better flows. To disable these warnings:

With Flow Builder API:

const flow = createFlow({
  flowId: "my-flow",
  startId: "welcome",
})
  .step({...})
  .withValidation(false) // Disable validation warnings
  .build();

const machine = useFlowMachine(flow);

With direct useFlowMachine:

const machine = useFlowMachine({
  ...flow,
  validateFlow: false, // Disable validation warnings
});

Common warnings:

  • NO_VALIDATION: Steps that accept input but have no validation function
  • UNREACHABLE_STEPS: Steps that cannot be reached from the start step
  • CIRCULAR_DEPENDENCIES: Steps with circular dependency chains

A/B Testing

import React from "react";
import {
  useABTest,
  useABTestManager,
  ABTestBuilder,
} from "@markiearnold/flow-machine";

function TestFlow() {
  // Create A/B test manager
  const {manager} = useABTestManager();

  // Create and register a test
  const test = new ABTestBuilder("welcome-message")
    .setName("Welcome Message Test")
    .addVariation("A", "Welcome!")
    .addVariation("B", "Hello there!")
    .setTraffic(50, "equal")
    .build();

  // Register the test
  React.useEffect(() => {
    manager.registerTest(test);
  }, [manager, test]);

  // Use the test
  const testResult = useABTest({
    userId: "user-123",
    testId: "welcome-message",
    manager,
  });

  return (
    <div>
      <p>{testResult.variation?.content || "Loading..."}</p>
    </div>
  );
}

Customization

Styling

All components support custom CSS classes and styling:

<FlowUI
  machine={machine}
  chatClassName="custom-chat-styles"
  className="custom-ui-styles"
/>

Custom Widgets

Add custom components to your flow:

<FlowUI machine={machine} customWidget={<MyCustomComponent />} />

Production-Ready Features

📱 Mobile Detection

Basic mobile device detection for responsive layouts:

import {useIsMobile} from "@markiearnold/flow-machine";

function ResponsiveComponent() {
  const isMobile = useIsMobile();

  return <div>{isMobile ? <MobileLayout /> : <DesktopLayout />}</div>;
}

Available Features:

  • ✅ Mobile device detection (useIsMobile hook)

  • ✅ Responsive breakpoint detection (768px)

  • ✅ Screen size monitoring

  • ✅ Retry logic for failed operations

API Reference

useFlowMachine

The main hook for managing flow state.

import {useFlowMachine, createFlow} from "@markiearnold/flow-machine";

const config = createFlow({
  flowId: "my-flow",
  startId: "welcome",
})
  .step({
    id: "welcome",
    prompt: "Hello!",
    next: () => null,
  })
  .build();

const machine = useFlowMachine(config);

Flow Templates

import {useTemplate} from "@markiearnold/flow-machine";

// useTemplate returns the flow machine state directly
const flowMachine = useTemplate("user-onboarding", {
  companyName: "Acme Corp",
  features: ["Feature 1", "Feature 2"],
});

A/B Testing

import {
  useABTest,
  useABTestManager,
  ABTestBuilder,
} from "@markiearnold/flow-machine";

// Create test manager
const {manager} = useABTestManager();

// Create test
const test = new ABTestBuilder("welcome-message")
  .setName("Welcome Message Test")
  .addVariation("A", "Welcome!")
  .addVariation("B", "Hello there!")
  .setTraffic(50, "equal")
  .build();

// Use test
const testResult = useABTest({
  userId: "user-123",
  testId: "welcome-message",
  manager,
});

Development

Building

npm run build

Development Mode

npm run dev

Type Checking

npm run type-check

Testing

npm run test              # Run all tests
npm run test:watch        # Run tests in watch mode
npm run test:coverage     # Run tests with coverage
npm run test:integration  # Run integration tests

📚 Documentation

Documentation is available in the /docs folder and includes:

  • Getting Started - Installation and basic usage
  • API Reference - Complete API documentation
  • Examples - Real-world usage examples
  • Advanced Features - A/B testing, templates, analytics, and more

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Documentation Development

To work on documentation:

npm run docs:dev        # Start docs dev server
npm run docs:build      # Build documentation
npm run docs:serve      # Serve built documentation
npm run docs:deploy     # Deploy to GitHub Pages

License

This project is licensed under the MIT License - see the LICENSE file for details.

💬 Community & Support

  • 📖 Documentation - Available in the /docs folder
  • 🐛 Bug Reports - Report issues on GitHub
  • 💡 Feature Requests - Suggest improvements on GitHub
  • 📦 npm Package - Install from npm
  • GitHub Repository - Source code and examples

Made with ❤️ for the React community. Star the repo if it helps you build amazing conversational UIs! 🌟