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

@ronaldroe/micro-flow

v1.3.6

Published

A lightweight, flexible workflow orchestration library for Node.js and browser environments. Build complex, sequential processes with ease using an intuitive API that supports conditional logic, flow control, event handling, and state management.

Downloads

442

Readme

Micro-Flow

Micro-Flow is a simple, lightweight, cross platform (browser and runtime) logic orchestration library. Micro-Flow makes async logic flows first-class objects — named, observable, pauseable, and composable — so a multi-step process is something you can reason about, monitor, and control, not just a wall of awaits.

Why Micro-Flow?

We've all been there: a 100-line async function that acts as a "black box" when it fails. You have to manually hard-code retries, timeouts, state logging, and progress tracking for every single task. It’s brittle, a nightmare to unit test, and impossible to pause or resume.

Micro-Flow makes your logic a first-class object. Instead of one giant function, you build a Workflow where every step is automatically tracked, timed, and controlled. It replaces "Try-Catch" boilerplate with professional orchestration.

Features

  • 🔍 Zero-Effort Observability - Lifecycle events (STEP_FAILED, WORKFLOW_COMPLETE) emit automatically — eliminate manual log-sprinkling.
  • ⏸️ Pause, Resume, & Rewind - Suspend any logic flow mid-pipeline and resume it later without losing local state.
  • 🌿 Declarative Branching - Use ConditionalStep and SwitchStep to keep complex branching logic out of your callables and in the workflow structure.
  • 🎯 Dynamic Flow Control - Break out of or skip steps dynamically at runtime.
  • 💾 Namespaced State Management - Access global state through a namespaced singleton with dot-notation support — eliminate data-threading through arguments.
  • Cross-Tab/Worker Sync - Broadcast events automatically via BroadcastChannel to reach other tabs and workers with zero configuration.
  • 🌍 Isomorphic by Design - Run the same API in Node.js (≥18) and all modern browsers.
  • 🎨 Framework Agnostic - Integrate seamlessly with React, Vue, Svelte, or vanilla JS.
  • Lightweight Core - ESM-first design with minimal production dependencies.

Installation

npm install --save micro-flow

Quick Start

Node.js Example

import { Workflow, Step } from 'micro-flow';

const workflow = new Workflow({
  name: 'data-processor',
  steps: [
    new Step({
      name: 'fetch-data',
      max_retries: 3, // Built-in resilience for flaky APIs
      callable: async () => {
        const response = await fetch('https://api.example.com/data');
        return response.json();
      }
    }),
    new Step({
      name: 'process-data',
      callable: async () => ({ processed: true })
    }),
    new Step({
      name: 'save-results',
      callable: async () => ({ saved: true })
    })
  ]
});

const result = await workflow.execute();

✨ Feature Spotlight: Cross-Tab Sync

Trigger logic in one tab and react to it in another. Events sync across workers and browser windows automatically:

import { State } from 'micro-flow';

// Listen for updates from other tabs/workers
State.get('events.workflow').on('sync-event', (data) => {
  updateUI(data);
});

// Broadcast to all other contexts
State.get('events.workflow').emit('sync-event', { status: 'updated' });

Browser: Coordinating UI Logic

import { Workflow, Step } from './micro-flow.js';

const workflow = new Workflow({
  name: 'ui-update',
  steps: [
    new Step({
      name: 'show-loading',
      callable: async () => {
        document.getElementById('loader').style.display = 'block';
      }
    }),
    new Step({
      name: 'fetch-data',
      callable: async () => {
        const response = await fetch('/api/data');
        return response.json();
      }
    }),
    new Step({
      name: 'update-ui',
      callable: async () => {
        document.getElementById('content').textContent = 'Data loaded!';
        document.getElementById('loader').style.display = 'none';
      }
    })
  ]
});

document.getElementById('loadBtn').addEventListener('click', () => {
  workflow.execute();
});

React: Decoupling Logic from Components

import { Workflow, Step, State } from './micro-flow.js';
import { useState } from 'react';

function DataFetcher() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);

  const fetchData = async () => {
    const workflow = new Workflow({
      name: 'fetch-workflow',
      steps: [
        new Step({ name: 'start', callable: async () => setLoading(true) }),
        new Step({
          name: 'fetch',
          callable: async () => {
            const res = await fetch('/api/data');
            const json = await res.json();
            setData(json);
          }
        }),
        new Step({ name: 'complete', callable: async () => setLoading(false) })
      ]
    });

    await workflow.execute();
  };

  return (
    <div>
      <button onClick={fetchData} disabled={loading}>
        {loading ? 'Loading...' : 'Fetch Data'}
      </button>
      {data && <pre>{JSON.stringify(data, null, 2)}</pre>}
    </div>
  );
}

Vue: Clean Reactive Lifecycle

<template>
  <button @click="runWorkflow" :disabled="isRunning">
    {{ isRunning ? 'Processing...' : 'Run Workflow' }}
  </button>
</template>

<script setup>
import { ref } from 'vue';
import { Workflow, Step } from './micro-flow.js';

const isRunning = ref(false);

const runWorkflow = async () => {
  const workflow = new Workflow({
    name: 'vue-workflow',
    steps: [
      new Step({
        name: 'process',
        callable: async () => {
          isRunning.value = true;
          await doAsyncWork();
        }
      }),
      new Step({
        name: 'finalize',
        callable: async () => { isRunning.value = false; }
      })
    ]
  });

  await workflow.execute();
};
</script>

Core Concepts

Workflows

Workflows execute a series of steps in sequence. Use them to manage:

  • Sequential execution and error handling.
  • Fine-grained pause and resume control.
  • Event emission for real-time monitoring.
  • Result aggregation and session tracking.

Steps

Orchestrate functions, other steps, or entire workflows as individual units of work. Every step includes built-in retry and timeout policies.

Callables

Define logic using callables. Assign any async function, step, or workflow to a step's callable parameter. This flexibility enables everything from simple logic chains to modularized, enterprise-scale flows.

State Management

Manage namespaced global state across all workflows and steps:

import { State } from 'micro-flow';

// Set and get values with dot-notation
State.set('user.name', 'John Doe');
const timeout = State.get('config.timeout', 3000);

// Merge or iterate over collections
State.merge({ settings: { theme: 'dark' } });
State.each('users', (user) => console.log(user.name));

Events

Monitor lifecycle events for workflows, steps, and state. Use Node's EventEmitter syntax or the browser's CustomEvent syntax—both support all environments.

Use Cases

Power Backend Processes (Node.js)

  • Data Pipelines - Build ETL and transformation workflows.
  • API Integrations - Orchestrate multi-step API calls with built-in retries.
  • Automation - Automate scheduled jobs and batch processing.
  • Microservices - Coordinate complex service calls.

Enhance Frontend Logic (Browser)

  • Multi-Step UI - Build registration flows and checkout wizards.
  • Data Fetching - Coordinate sequential API calls with caching.
  • Animations - Sequence complex UI animations.
  • State Sync - Sync auth state and shopping carts across tabs instantly.

Documentation

Explore the full documentation in the docs directory: