Declarative
Workflow DSL
for

Define workflow pipelines in YAML. Execute your flow anywhere. Ideal for deterministic orchestration.

duckflux logo
scroll

Design Philosophy

duckflux isn't "another DSL". It's an easy workflow engine for the 2000 century developers.

Declarative-first

Describe what your workflow should do. YAML is the source of truth: readable, version-controlled, diffable.

Deterministic

A state machine β€” not an LLM β€” controls flow. Your pipeline runs the same way every time. No hallucinated next steps.

Multi-runtime

The spec is implementation-agnostic. Same YAML, any runtime. Currently supporting any platform using binaries or Node/Bun environments.

Powered by Google CEL

Google Common Expression Language for all conditional logic. Type-safe, sandboxed, and battle-tested in Kubernetes.

Batteries included

Redis, NATS and custom event hubs. A Mermaid-powered editor. A web server UI for observability.

Focused on DX

For developers without a PhD in distributed systems. Simple YAML with great capabilities.

Powered by Google CEL

Google's Common Expression Language keeps your logic safe, predictable, and readable. The same engine that powers Kubernetes admission controllers.

Type-safeSandboxedNo side effectsFast evaluationKubernetes-provenHuman-readable
workflow.duck.yaml
steps:
  - run: analyze
    output: result

  - run: approve
    when: "result.score >= 0.9 && result.issues.size() == 0"

  - run: review
    when: "result.score >= 0.6 && result.score < 0.9"

  - run: reject
    when: "result.score < 0.6"

CEL expressions used

result.score >= 0.9

Direct field access with comparison

result.issues.size() == 0

CEL built-in: list length check

&&

Boolean AND β€” both conditions must be true

Building Blocks

Every step in a duckflux workflow is powered by a participant. Six types cover everything from shell commands to event-driven coordination.

πŸ’»
exec

Shell commands & scripts

Execute any shell command, script, or binary. Perfect for AI agent CLIs, build tools, or custom runners.

Full exec reference
example.duck.yaml
participants:
  coder:
    type: exec
    command: >
      claude --model claude-opus-4-5
      --prompt "{{ inputs.task }}"
      --output-format json

Tooling & Ecosystem

Everything you need to author, run, observe, and debug workflows β€” from the terminal to the browser.

⌨️
CLI

Run, lint & validate

Run workflows from the terminal with a single command. Lint for schema and semantic errors. Validate inputs before execution. Supports NATS and Redis event backends for cross-process coordination.

CLI reference
terminal
# Install globally
bun add -g duckflux

# Run a workflow
duckflux run ./pipeline.duck.yaml --input repo=org/app

# Lint before running
duckflux lint ./pipeline.duck.yaml

How duckflux Compares

The same workflow scenario across tools: a coder implements, a reviewer reviews, if not approved repeat up to 3 times, then deploy.

Feature duckflux YAML DSL Argo K8s CI/CD GHA GitHub CI n8n Visual automation Temporal Durable workflows Airflow Data pipelines
Conditional loop native template recursion unroll JS hack code impossible
Fixed loop native native βœ— JS hack code βœ—
Parallelism native native jobs visual goroutines native
Conditional branch native when if IF node code BranchOp
Guard (when) native when if per step βœ— code βœ—
Events (emit/wait) native βœ— βœ— webhook signals sensors
Error handling onError + retry retryStrategy continue-on-error βœ— code βœ—
Sub-workflows native template ref reusable sub-workflow child wf SubDagOp
Spec is readable βœ“ partially partially βœ— (JSON) βœ— (code) βœ— (Python)
Inline participants native βœ— βœ— βœ— βœ— βœ—

Based on publicly available documentation. Table reflects capabilities, not quality.

Ready to quack?

Stop orchestrating
imperatively.

Write your first workflow in 5 minutes. Run it with a single command. Let duckflux handle the state machine so you can focus on what matters.

$ duck run ./hello.duck.yaml