Concepts

The concepts of Inflow

One page for the whole mental model. Inflowenger is a runtime whose logic is a workflow graph — a substrate on which you can build large classes of systems (ERP, CRM, automation platforms) where an operator defines and changes logic without redeploying.

01 — The claim

A small set of primitives spans everything

The platform ships only a handful of primitive node types. Every higher-level node a product could want — an “HTTP call”, a “send email”, an “approval gate”, a “save to DB” — compiles down to one of them. The single open-ended extension point, the Plugin, covers the rest.

With only these low-level node types you can build any higher-level node, and therefore any system a workflow builder needs.

Void

VoidNodeType

No-op: start markers, join points, dead-ends.

Deep dive →

Code

CodeNodeType

Run JS/OPA logic, write the result into context.

Deep dive →

Contract

RuleNodeType

Branch: the rule output is tags selecting which transitions fire.

Deep dive →

Extrinsic

ExtrinsicNodeType

Call an internal service you own over NATS request/reply.

Deep dive →

Plugin

PluginNodeType

Hand off to a live external process with its own UI and jobs.

Deep dive →

GoTo

GoToNodeType

Jump into another (or the same) flow and return.

Deep dive →

Code, Contract, Extrinsic, GoTo and Void are compiled primitives. Plugin is the exception — it never compiles away, because it is a real external process. That's what makes it the platform's richest, open-ended node.

02 — Control flow

One node decides branches

A node with a single output is a linear step: it runs, then the engine follows its one transition. A node with many outputs is a branch — and branching is exactly what the Contract node is for. A Contract's rule returns a list of tags; the engine follows only the transitions whose tags match. “Three outputs: success / retry / reject” is just one Contract node with three tagged handlers.

node with 1 output──►any linear primitive + one transition
node with N labelled outputs──►a Contract; its rule picks the matching tag(s)
node that reads “inputs”──►context read inside the node (via its scope)
node with a config form──►form values stored on the node, read by the compiler
03 — The platform

Four actors, talking over NATS

A backend built with inflow-fusion is one of four actors. They coordinate over NATS request/reply rather than a shared database — which is what lets one engine serve many different backends.

Infra (control plane)

Owns accounts and identity: issues NATS credentials, tracks which engine instances exist, and hands out the per-account NATS accounts everything authenticates against.

Your backend (the SDK)

Owns the actual product data — flow definitions, execution context, business entities. It does not execute flows; it answers three questions over NATS and can expose extra domain actions as extrinsic services.

Inflow engine instance(s)

The execution runtime. Given a process request it walks the compiled node graph, asking your backend for what it doesn't have and executing each node by type.

Plugins

Isolated external integrations a flow's Plugin node talks to over NATS. Each gets its own scoped credentials so it can only see subjects that belong to it.

04 — From canvas to execution

How a drawn graph becomes something the engine runs

None of the shapes a designer draws reach the engine directly. The engine only ever executes a map of primitive nodes. A compiler sits in between.

  1. AuthorDrag nodes onto a canvas, configure them through drawers, connect their handles.
  2. SaveThe raw editor graph — nodes + edges — is persisted verbatim. No translation happens on the frontend.
  3. CompileA per-node hook reads each node's form data and builds the matching primitive; the compiler fills in transitions from the edges.
  4. ExecuteAn engine instance fetches that node map and walks it, asking your backend for whatever it needs.

The hook is the only place product-specific knowledge lives — the seam that makes the primitives claim real. Your node types are your frontend's convention; the hook declares which primitive each one means. The full walk-through is in From a frontend node to a primitive.

05 — Why it's enough

The design argument

Computation

Code (JS / OPA) covers arbitrary transformation of context.

Decision & control flow

Contract covers branching, GoTo covers reuse across flows, Void covers structure.

Reaching your own system

Extrinsic reaches any internal service you own via one request/reply subject.

Reaching the outside world

Plugin, a live process, covers everything the compiled primitives can't — open connections, background loops, its own UI.

Those axes span what a workflow builder needs, which is why the primitive set is closed.