Feature · Workflow engine

Flow

Design a workflow on a canvas a person and an agent share, then run that same graph in the browser, on Node, in PHP or in Python. One JSON document, one set of outputs, wherever it runs.

Node / TypeScriptPHPPython
MCP readyfancy-flow v0.81.0
WorkflowSchema v1one JSON graph
The Flow editorLive demo
Loading the Fancy Flow editor…

Pick an example and press Run. A User Input node opens a real form and waits for you; only the model and data calls are stubbed. Every canvas is documented with sticky notes.

One trigger, three workflowsLive engine
Deal #41: in the database

Guarded. Same three workflows, same order. The only difference is that the guard, deals.has(41), is re-checked immediately before each one starts. Not at dispatch: the hazard is what changed in between.

  1. Enrich dealDeal updated → Score & enrichwaitingNot run yet.
  2. Archive dealDeal updated → Archive + deletewaitingNot run yet.
  3. Notify ownerDeal updated → Email the ownerwaitingNot run yet.
import { runCohort } from "@particle-academy/fancy-flow/engine";

await runCohort([enrich, archive, notify], executors, undefined, {
  guard:  () => deals.has(41),              // re-checked before EACH workflow
  reason: () => "deal #41 no longer exists", // recorded on the skipped result
});

On a queue it is the same contract, made durable: FancyFlow::dispatchCohort() in fancy-flow-php enqueues only the head, hands the cohort on as each run settles, and records a skipped run's reason on the run itself. A run parked on a human approval holds the cohort until someone decides.

This is the real runCohort from @particle-academy/fancy-flow/engine, running in your browser over three real graphs. Fire it unguarded first: the interesting part is that nothing breaks.

One graph, run anywhere

The editor is where a graph is designed. Everything else is about where it runs, and who else can work on it.

A zero-React engine

@particle-academy/fancy-flow/engine runs a graph with no React, no DOM and no React Flow, on a server, a queue worker or a CLI. The editor is only for designing. The cohort demo above runs on it.

PHP and Python twins

fancy-flow-php and fancy-flow-py run the same WorkflowSchema v1 JSON with the same outputs, and refuse a document without version: 1 the same way. The PHP twin adds queued, durable runs that resume from a checkpoint.

A node marketplace, vendored

A marketplace node is source, not a package: npx fancy-cli@latest add node <kind> copies its editor kind and its JS and PHP backends into your project, so adding one adds no dependency.

A shuttle for AI, not an engine

Core declares a registerLlmClient contract and never imports a provider SDK. Opt-in adapters live on their own subpaths: ./llm/vercel-ai and ./llm/prism.

Cohorts and human pauses

runCohort re-checks a guard before each flow one trigger fires. A node waits for a person through the public pauseForHuman / decodePause contract, the same way the built-in approval and input nodes do.

Agents build on the same graph

The editor is controlled state, so registerFlowBridge lets an agent add, wire and run nodes on the canvas you see. On Laravel, fancy-flow-mcp builds workflows headlessly with deterministic, port-validated tools.

The node marketplaceLive registry

Read live from /r/nodes/index.json, the index the CLI installs from. The 31 core kinds ship inside fancy-flow 0.81.0 and are not listed: there is nothing to install.

In the editor

Notes on the canvas

A first-class note kind documents a flow in place. The engine skips notes, so their text never reaches a runner.

Swimlanes

Resizable lanes group the graph; drop a node in to file it. Lanes never execute, and edges cross them freely.

Undo, redo and staged deletes

Every committing edit is one reversible step (Ctrl+Z, Ctrl+Shift+Z). A confirmDelete hook lets a person approve what an agent removes.

Auto-layout

One click arranges the graph, or one lane's children, into a readable DAG with dagre, bundled and lazy-loaded.

Copy and paste subgraphs

Ctrl+C and Ctrl+V keep the wiring between the copied nodes intact; duplicate, align and distribute a selection.

Validated wiring

Drag an endpoint to rewire. A type-incompatible port pairing is refused by the same rule an agent's flow_connect obeys.

How it fits

The React package is the editor and the TypeScript engine; PHP and Python are runtime twins of that engine, and fancy-flow-mcp is a Laravel MCP server for building graphs without a canvas.

Human+ bridge

An agent drives this surface over MCP, through the same state a person sees, never the DOM.

  • import { registerFlowBridge } from "@particle-academy/agent-integrations/bridges/flow";tools: flow_*

Install

Install the runtime you need. Nodes from the marketplace are added with the CLI, never installed as a package.

  1. fancy-flowNode / TypeScript
    npm install @particle-academy/fancy-flow
  2. particle-academy/fancy-flow-phpPHP
    composer require particle-academy/fancy-flow-php
  3. fancy-flowPython
    pip install fancy-flow
  4. particle-academy/fancy-flow-mcpPHP
    composer require particle-academy/fancy-flow-mcp

The packages

Build your first flow

Start from the Workflow Studio starter kit, or read the fancy-flow docs for the editor, the engine and the node contract.