Skip to content

Runtime overview

Run any DuckFlux workflow with a single command. Or embed the engine directly in your TypeScript app. Either way, you get the same full-featured runtime — with no vendor lock-in, no agent framework to learn, and no infrastructure to manage by default.

Terminal window
quack run workflow.yaml --input env=production

Install once, run anywhere. The quack binary reads your YAML, validates it, and executes it. No code, no build step, no config files.

Terminal window
# Run from npx/bunx without installing
bunx duckflux run workflow.yaml --input name=World
# Or install globally
bun add -g duckflux
quack run workflow.yaml

Works with Bun and Node.js. Inputs from flags, files, or stdin. Structured output to stdout. Exit codes for CI. See the CLI reference for all flags.

Drop @duckflux/core into any TypeScript project and call executeWorkflow directly. No subprocess, no glue scripts, no serialization overhead — the workflow runs in-process.

import { executeWorkflow } from "@duckflux/core/engine";
import { parseWorkflowFile } from "@duckflux/core/parser";
const workflow = await parseWorkflowFile("./pipeline.yaml");
const result = await executeWorkflow(workflow, { env: "production" });
console.log(result.output); // structured output
console.log(result.steps); // per-step results, timings, errors

Full TypeScript types. Programmatic input/output. No side effects unless you ask for them. See the library API reference.


The runtime implements the complete DuckFlux v0.7 spec — every participant type, every flow construct, every expression feature:

  • Participantsexec (shell), http, emit (events), workflow (sub-workflows)
  • Control flowloop, parallel, if/else, when guards, set, wait
  • I/O chaining — step output flows automatically as input to the next step
  • Expressions — full CEL standard library with has, size, matches, timestamp, duration, and more
  • Error strategiesfail, skip, retry with exponential backoff, and fallback participants
  • Timeouts — per-step or global, with override precedence

Async workflows that emit and wait on events work out of the box with the built-in in-memory hub — no external services needed. Scale up to NATS or Redis when you need cross-process delivery.

BackendExtra packageCross-processReplay
In-memorynoneNoYes
NATS JetStream@duckflux/hub-natsYesNo
Redis Streams@duckflux/hub-redisYesYes

See Event hub providers for setup and configuration.

Every run can produce a structured trace — one file per execution, written incrementally as each step completes. Choose the format that fits your workflow: JSON for downstream processing, TXT for quick human inspection, or SQLite for SQL queries across multiple runs.

Terminal window
# Trace to JSON (default)
quack run workflow.yaml --trace-dir ./traces
# Query with any SQL client
quack run workflow.yaml --trace-dir ./traces --trace-format sqlite

Each trace captures every step — participants and control-flow constructs alike — with timing, inputs, outputs, errors, and retry counts. See Execution tracing for the full format reference.


The runtime ships as focused, composable packages:

PackageInstallUse when
duckfluxbun add -g duckfluxYou want the CLI
@duckflux/corebun add @duckflux/coreYou want to embed the engine
@duckflux/hub-natsbun add @duckflux/hub-natsYou need NATS event delivery
@duckflux/hub-redisbun add @duckflux/hub-redisYou need Redis event delivery