dagnats
v 0.1 license Apache-2.0 github docs

dagnats

A workflow engine for durable jobs and autonomous LLM coding pipelines. NATS is the only dependency. The deploy artifact is one Go binary.

Projectdagnats — DAG workflow engine
LanguageGo (module github.com/danmestas/dagnats)
Runtime depsNATS JetStream (embedded)
Binaries1 (dagnats serve = orchestrator + API + triggers + NATS)
LicenseApache-2.0
Statusv0.1 · alpha · breaking changes possible
§01

Install install

shell
$ go install github.com/danmestas/dagnats/cmd/dagnats@latest
$ dagnats serve

That is the entire install. There is no step three. dagnats serve starts an embedded NATS server, the orchestrator, the API, and the trigger system in one process.

§02

What it is overview

dagnats is a Go workflow engine. You describe work as a directed acyclic graph of tasks; dagnats runs the graph, retries failures, recovers from crashes, and reconstructs state from an immutable event log.

Its only infrastructure dependency is NATS JetStream, which is embedded in the same process. There is no Postgres to migrate, no Redis to monitor, no separate broker to configure.

Two audiences benefit. Backend engineers needing durable workflows that survive restarts get a single binary instead of a small fleet of services. Teams building autonomous coding pipelines get first-class step types — AgentLoop, Planner, Approval, WaitForEvent — that other engines treat as application-layer concerns.

§03

Why you might want it why

  1. One binary, zero external databases. The deploy is scp dagnats user@host && ./dagnats serve. No Postgres migrations. No Redis to operate. No broker.
  2. Crash-safe by default. Workflow state is event-sourced into JetStream and snapshotted in KV. Kill the process, start it again, in-flight work resumes from the last event.
  3. Agent loops are first-class. AgentLoop, Planner, Approval, and Continue-As-New are step types in the workflow language — not patterns you reimplement per project.
  4. Inspectable. Every event is a JSON message on a stream. nats sub "history.>" tails any workflow run live, in any terminal.
  5. Bounded. No unbounded queues. No unbounded retries. No recursion. Every loop has a fixed upper bound. (TigerStyle — safety first.)
§04

How it fits together architecture

dagnats architectureTriggers send events to the orchestrator. The orchestrator advances the DAG, dispatches tasks to workers, and receives results back. All workflow state lives in NATS JetStream and KV.triggersorchestratorworkerscronwebhooksubjectconsume eventadvance DAGsnapshot KVworkerworkerworkerJetStream + KVeventstasksresultsstate

All workflow state lives in NATS JetStream + KV — that is the entire system. There is no separate database.

§05

Compared to neighbors comparison

dagnatsTemporalHatchetInngest
StackNATS onlyPG + CassandraPG + RabbitMQPG + Redis
Binaries1~5~3hosted
OSSyesyesyespartial
Native agent stepsyesnoyesyes
SDKsGo + HTTP bridgemany33
Self-hosttrivialinvolvedmoderaten/a

Comparison reflects open-source distributions as of writing. Approximate; orientation only.

§06

What it is not limits

dagnats is young. It is single-tenant by design. There is one Go SDK plus an HTTP bridge for everything else; if you need a native TypeScript or Python SDK, you will be writing it.

Don't reach for it for sub-millisecond task routing (use a queue). Don't reach for it for embarrassingly-parallel batch jobs without dependencies (use a worker pool). Don't reach for it where eventual consistency would surprise you (use a database with transactions).

§07

Get going start

shell
$ go install github.com/danmestas/dagnats/cmd/dagnats@latest
$ dagnats serve                              # one process, embedded NATS
$ dagnats workflow register hello.json
$ dagnats run start hello --watch

Walkthrough: /docs/get-started · Architecture: /docs/architecture · SDK reference: /docs/reference/sdk · Source: github.com/danmestas/dagnats.