cd /news/developer-tools/stepyard-local-yaml-pipelines-with-a… · home topics developer-tools article
[ARTICLE · art-29360] src=github.com ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

Stepyard – local YAML pipelines with a Python escape hatch, no server needed

Stepyard, a local-first automation runner for developers, has been released. It enables Git-versioned YAML workflows with Python plugins and private LLM automations without requiring a server. The tool runs flows in isolated OS subprocesses and includes a built-in scheduler for cron, interval, or startup triggers.

read4 min views1 publishedJun 16, 2026

Stepyard is a local-first automation runner for developers who want Git-versioned workflows, Python plugins, and private LLM automations - without running a workflow server.

pip install stepyard
stepyard init my-automations && cd my-automations
stepyard run hello

Build a container, smoke-test it, summarise the result with an LLM, and post to Slack. One YAML file, no glue scripts.

name: deploy
description: Build the image, smoke-test it, and post an AI summary to Slack.

steps:
  - id: build
    uses: shell.run
    with:
      command: docker build -t myapp:${{ env.GIT_SHA }} .

  - id: smoke_test
    uses: http.request
    with:
      method: GET
      url: https://staging.myapp.com/healthz

  - id: summary
    uses: llm.generate            # built-in - reads OPENAI_API_KEY from the env
    with:
      model: gpt-4o-mini
      prompt: |
        Write a one-line Slack message about this deploy.
        Build exit code: ${{ steps.build.output.code }}
        Health check HTTP status: ${{ steps.smoke_test.output.status }}

  - id: notify
    uses: http.request
    with:
      method: POST
      url: ${{ env.SLACK_WEBHOOK }}
      json_body:
        text: ${{ steps.summary.output.output }}

Run it:

GIT_SHA=$(git rev-parse --short HEAD) stepyard run deploy
✓  build         12.4s
✓  smoke_test     0.3s
✓  summary        0.9s
✓  notify         0.2s

Flow completed in 13.8s

Reading step outputs.Each node has a documented output shape, referenced as${{ steps.<id>.output... }}

:

Node output

shapeshell.run

{ stdout, stderr, code }

http.request

{ status, headers, body }

llm.generate

{ output, usage, model, provider }

(use${{ steps.<id>.output.output }}

for text)Full reference:

[.]docs/nodes/builtin.md

Flows are YAML files in your repo. Steps, conditions, loops, and retries are plain keys. Version-control them alongside your code; no proprietary DSL to learn.Extend with plain Python. One@node

decorator turns any function into a reusable step. Inputs are type-validated automatically; plugin dependencies run in an isolated virtualenv, so they never clash with Stepyard's own.Nothing leaves your machine. State is stored in a local SQLite database. Data only goes out if a step in your flow explicitly sends it.Every run is its own process. Each flow executes in a dedicated OS subprocess, so a crash, timeout, orsys.exit

in one run cannot take down the scheduler or a sibling run. SeeExecution model.Built-in scheduler, no hosted service. Add atrigger:

block withcron

,interval

, orstartup

, runstepyard service start

, and flows execute on schedule without a control plane.

pip install stepyard

git clone https://github.com/rorlikowski/stepyard && cd stepyard
uv pip install -e ".[dev,docs]"
uv run stepyard doctor      # verify the install

Requires Python 3.10+. Works on macOS, Linux, and Windows (WSL).

stepyard init my-automations   # scaffold flows/ + .gitignore + .stepyard/
cd my-automations

stepyard run hello             # run a flow now (in its own subprocess)
stepyard status               # see every flow and its latest run
stepyard show <run-id>        # drill into the steps of one run
stepyard logs <run-id>        # stream the captured logs
stepyard validate --all       # type-check your YAML without running it

Schedule it instead of running by hand - add a trigger and start the daemon:

name: nightly_backup
trigger:
  uses: cron
  with:
    schedule: "0 3 * * *"      # every day at 03:00

steps:
  - id: dump
    uses: shell.run
    with:
      command: pg_dump ${{ env.DATABASE_URL }} | gzip > /tmp/backup.sql.gz
stepyard service start          # run the scheduler in the background
stepyard service status

Stepyard is deliberately process-isolated:

(stepyard run <flow>

spawns a fresh subprocesspython -m stepyard.engine.runner

) for that single run. Its stdout/stderr are captured to.stepyard/logs/

.The scheduler daemon(stepyard service start

) runs separately. It evaluates triggers, enqueues runs in SQLite, and a worker spawns one subprocess per run (bounded bySTEPYARD_MAX_CONCURRENT_FLOWS

, default4

).Inside a run, steps execute sequentially. Built-in nodes run in-process; plugin nodes installed into an** isolated virtualenv**run in asecondshort-lived subprocess that talks JSON over stdin/stdout - so a plugin's dependencies can never clash with Stepyard's own.

The practical upshot: one misbehaving flow or plugin cannot corrupt the scheduler or sibling runs.

from stepyard.sdk import node, NodeResult, NodeStatus

@node(name="math.add")
def add(a: int, b: int) -> int:
    return a + b

@node(name="files.archive")
def archive(path: str) -> NodeResult:
    if not path:
        return NodeResult(status=NodeStatus.FAILED, error="path is required")
    return NodeResult(status=NodeStatus.SUCCESS, output={"archived": path})

Register it via an entry point and it becomes available as uses: math.add

in every flow. See docs/plugins/creating.md.

Section What's inside

Core ConceptsHow-to GuidesBuilt-in NodesPlugin DevelopmentCLI ReferenceThe full documentation is published at ** rorlikowski.github.io/stepyard**.

Browse the docs locally with uv run mkdocs serve

.

MIT - see LICENSE.

── more in #developer-tools 4 stories · sorted by recency
── more on @stepyard 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/stepyard-local-yaml-…] indexed:0 read:4min 2026-06-16 ·