A stateless, snapshot‑based, and serverless‑ready workflow engine for JavaScript.
Refluxo is a lightweight engine designed for modern distributed environments. Unlike traditional engines that "run" a process, Refluxo transitions states. It takes a snapshot, processes a step, and returns a new snapshot. This makes it the perfect backbone for "Human-in-the-loop" systems, long-running processes, and serverless architectures.
"Build your own n8n or Zapier-like automation platform with ease."
Refluxo is isomorphic. It runs wherever JavaScript runs:
- Serverless: Designed to run on AWS Lambda, Cloudflare Workers, Vercel, etc. No background processes required.
- Runtime: Node.js, Bun, Deno.
- Browser: React, Vue, Svelte, or vanilla JS.
Every execution step is serializable. Pause a flow, save it to a database, and resume it days later.
While not intrinsic to the core, most projects benefit from strict data contracts. We offer the optional @refluxo/standard-schema-middleware (coming soon) to integrate with Standard Schema libraries like Zod or Valibot. You are free to implement your own validation logic or skip it entirely.
If you store your schema outside code, like in a database, you can write a logic to convert it to a Standard Schema object, for a example, read the docs
Dynamic data mapping is often essential for complex workflows. We offer @refluxo/jexl-middleware to provide JEXL-based expressions (similar to n8n). You are free to implement your own expression engine (e.g., using JavaScript eval or another library) or skip it entirely.
Refluxo's core is minimal, providing the primitives to build complex systems. Features like Human-in-the-loop (pausing for approval), Webhooks, or Scheduled Tasks are patterns you implement using the engine's pause/resume capabilities and external payload injection. You have full control over how state is stored and how events trigger workflows.
Define dynamic retry policies (fixed or exponential backoff) using expressions.
pnpm add @refluxo/core @refluxo/jexl-middlewareExecutors are pure logic. They receive resolved data and return an output.
import { NodeDefinition } from '@refluxo/core';
import * as v from 'valibot'; // or any other
const httpRequest: NodeDefinition = {
// Validation is optional and can be handled by middleware
// metadata: {
// input: v.object({ ... }),
// },
async executor(data, context) {
const response = await fetch(data.url);
const json = await response.json();
return { data: json };
},
};Workflows are plain JSON objects, making them easy to store and fetch from a frontend or database.
const workflow = {
nodes: [
{ id: 'start', type: 'http_request', data: { url: 'https://api.example.com/data' } },
data: { check: '{{ nodes.start.last.data.status === "ok" }}' }
],
edges: [
{ source: 'start', target: 'check_status' },
{ source: 'check_status', target: 'notify_node', sourceHandle: 'true' }
]
};You can pause execution to wait for an event or manual approval.
// In your executor
async executor(data, context, externalPayload) {
if (!externalPayload) {
return { data: {}, __pause: true }; // Engine will stop here
}
return { data: externalPayload }; // Resumes with the payload
}
// Executing
const engine = new WorkflowEngine({ workflow, nodeDefinitions });
let snapshot = await engine.execute({ initialNodeId: 'start' });
// ... later, when the user approves ...
snapshot = await engine.execute({
snapshot,
externalPayload: { approvedBy: 'admin_id' }
});Retries can be static or dynamic, driven by expressions.
const apiNode = {
type: 'api_call',
retryPolicy: {
maxAttempts: 'nodes.config.last.data.retryCount',
interval: 5000,
backoff: 'exponential'
},
// ...
};- Stateless by Design: No need for a persistent event loop. The state is in your database, not in memory.
- Highly Extensible: Replace the Expression Engine or the Validation logic easily.
- Traceable: Metadata tracks totalExecutionTime, attempts, and every node output, making debugging a breeze.
- Developer Friendly: Built with TypeScript for full type safety.
- Automation Platforms: Build a custom Zapier/n8n for your niche.
- Approval Workflows: Systems that require human intervention (e.g., Expense approval).
- Scheduled Tasks: Flows that wait for a specific date or time to continue.
- Complex Orchestration: Microservices coordination with automatic retries.