DOC_INDEX
THEME
DOCS/Learn OrchStep/Using Modules

Using Modules

Import reusable workflow units - local or remote - and call their tasks with config and per-call overrides

A module is just a directory with an orchstep.yml - no manifest required. Import it, then call its tasks like local ones. Modules are how workflow logic gets shared across projects and teams.

A minimal module

modules/notify/orchstep.yml:

name: notify
desc: "Send a message to a channel"

defaults:
  channel: "general"
  prefix: "INFO"

tasks:
  send:
    steps:
      - name: emit
        func: shell
        do: 'echo "[{{ vars.prefix }}] #{{ vars.channel }}: {{ vars.message }}"'
        outputs:
          line: "{{ result.output }}"

Importing and calling it

name: app-workflow

modules:
  - name: notifier
    source: "./modules/notify"
    config:
      channel: "deploys"        # workflow-wide setting for this module

tasks:
  main:
    steps:
      - name: ping
        module: notifier
        task: send
        with:
          message: "build finished"

      - name: ping_alerts
        module: notifier
        task: send
        with:                    # per-call overrides beat config
          channel: "alerts"
          prefix: "WARN"
          message: "disk usage high"

Verified output:

[INFO] #deploys: build finished
[WARN] #alerts: disk usage high

The layering: module defaults < import config: < per-call with:. Module outputs surface on the calling step - steps.ping.line.

Two verified gotchas

with: values are strings. Compare numerically in JavaScript inside the module (Number(vars.orders) >= Number(vars.min_orders)) rather than with Go-template gt, which errors on mixed types.

Templates in with: are rendered at the call site - so with: { min_orders: "{{ vars.min_orders }}" } correctly picks up --var overrides from the calling workflow.

Remote modules

modules:
  - name: release
    source: "git:https://github.com/orchstep/orchstep#git-release/v1.0.0"
  - name: scanner
    source: "@orchstep/demo-security-scan"     # registry scope
    version: "^1.0.0"

See Modules - Registry & Scopes for scope resolution and the official @orchstep/* catalog.

Run it

orchstep run

See it composed

The Modular Data Pipeline use case builds a multi-region ETL from three modules - including parallel module fan-out and a quality gate with CLI-tunable thresholds.