Click Here to complete the Micro-Flow user survey. It will take less than 5 minutes of your time.
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.
Imperative async functions frequently turn into untraceable "black boxes" when they fail. Managing retries, timeouts, state logging, and progress tracking within complex logic chains usually requires writing brittle, custom boilerplate for every single task. This approach complicates unit testing and makes features like pausing or resuming execution nearly impossible to implement cleanly.
Micro-Flow treats logic as a first-class object. Instead of managing one monolithic async function, you construct a structured Workflow where every individual step is automatically monitored, timed, and controlled. It replaces manual try-catch boilerplate with a resilient runtime framework designed for complete predictability and explicit execution tracking.
- 🔍 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
ConditionalStepandSwitchStepto 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
BroadcastChannelto 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.
npm install --save micro-flowimport { 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();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' });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();
});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>
);
}<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>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.
Orchestrate functions, other steps, or entire workflows as individual units of work. Every step includes built-in retry and timeout policies.
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.
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));Monitor lifecycle events for workflows, steps, and state. Use Node's EventEmitter syntax or the browser's CustomEvent syntax—both support all environments.
- 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.
- 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.
Explore the full documentation in the docs directory: