Trax

Trax is a .NET framework for business logic you can call, schedule, serve as an API, or move to workers, with every run recorded in your Postgres.

You write a train: a typed pipeline of small steps called junctions, where a failing junction skips the rest and the train returns the exception. Call it from a controller, put it on a cron schedule, publish it as a GraphQL mutation, or send it to a worker on another machine or in AWS Lambda. It is the same class each time, and every run leaves a record: when it started, how it ended, which junction failed and the exception it threw. Trax is MIT licensed and targets .NET 10.

New here? Start with the Getting Started guide.

The vocabulary

The type names in the API follow a train metaphor:

TermWhat it means
TrainA pipeline that follows a route, always stays on the tracks, always reaches a destination
RouteThe path a train follows: a sequence of junctions (IRoute<TIn, TOut>)
JunctionA point on the route where work happens (Junction<TIn, TOut>). The train either continues right (success) or switches left (failure)
Right trackSuccess path. The train continues to the next junction
Left trackFailure path. The train bypasses remaining junctions and arrives with the exception
MemoryThe cargo the train carries between junctions, wired automatically by type
ServiceTrainA Train with equipment bolted on: execution tracking, logging, lifecycle management

A train never leaves the rails. It always reaches a destination, either the intended output (right) or an exception (left). You'll see these terms throughout the docs and the API surface. The Glossary defines the rest: Effect, Metadata, Manifest, the work queue, dead letters and the other names the docs use.

Use only what you need

Each package adds one layer of capability. Stop at whatever layer solves your problem.

LayerWhat it adds
CoreTyped pipelines, error propagation, chains declared in Junctions() that can be checked before they run
EffectExecution metadata, dependency injection, pluggable effect providers
MediatorDecoupled dispatch: route by input type instead of direct injection, and the startup check that refuses to start a host whose chains cannot run
SchedulingCron/interval scheduling, retries, dead-letter handling, job dependencies
APIAuto-generated GraphQL via HotChocolate
DashboardBlazor monitoring UI that mounts into your existing app

Where to go