BLOG/BY ROLE
THEME
BY ROLE

OrchStep for frontend developers

Frontend work means running the same five checks CI runs — lint, types, tests, build — against the right API base URL, then shipping a preview. Here's how to make that one workflow instead of five memorized commands.

Apr 21, 2026 OrchStep Team 6 minROLE: Frontend DeveloperSCALE: Any
RUNNABLE DEMO
Full source for this post: blog/frontend-dev-tasks
VIEW SOURCE

You push a branch, CI goes red on a lint rule, and you spend the next ten minutes reproducing it locally — because the exact command CI runs lives in a YAML file you don't read. So you run npm run lint, then tsc, then the tests, then a build, one at a time, hoping you matched the pipeline's order and flags.

Then there's the API base URL question. Did this build point at staging or production? It's an env var three layers deep in a .env file, and getting it wrong means a preview that silently talks to the wrong backend.

This post collapses that into one OrchStep workflow: a check task that runs exactly what CI runs, and a preview task that builds and ships a preview URL. Same eslint, tsc, vitest, and bundler — just ordered and named so the laptop and the pipeline run the identical thing.

The pain, concretely

  • CI fails on a check you can't easily reproduce because the command lives in pipeline YAML.
  • "Which API did this build hit?" is a question you answer by reading .env files.
  • The test step flakes on a slow CI runner, and you can't tell a real failure from a timeout.

The workflow

check is the CI mirror: install, lint, types, test, build — in order. preview reuses check as its first step, then deploys the build output and reports the URL. Because preview calls check, there is one definition of "is this branch shippable."

orchstep.yml
name: web-app
defaults:
  api_base: "https://api.staging.example.test"
  build_dir: dist
tasks:
  # `orchstep run check` — the same checks CI runs
  check:
    steps:
      - name: install
        func: shell
        do: echo "installing deps for web-app"
      - name: lint
        func: shell
        do: echo "running eslint + prettier"
      - name: types
        func: shell
        do: echo "running tsc --noEmit"
      - name: test
        func: shell
        do: echo "running vitest"
        retry:
          max_attempts: 2
          interval: "1s"
          backoff_rate: 2.0
      - name: build
        func: shell
        do: echo "building against {{ vars.api_base }} into {{ vars.build_dir }}"

  # `orchstep run preview`
  preview:
    steps:
      - name: build
        task: check              # ship only what passed the checks
      - name: deploy
        func: shell
        do: echo "uploading {{ vars.build_dir }} to preview host"
        outputs:
          url: "https://pr-42.preview.example.test"
      - name: report
        func: shell
        do: echo "preview ready at {{ steps.deploy.url }}"

The api_base is a named variable with a visible default, not a buried env var — and you override it for a one-off build with --var api_base=https://api.example.test, no .env editing. The deploy step captures the preview URL as an output, so the report step references that captured value instead of you copy-pasting it from scrollback.

Run the exact checks CI runs

orchstep run check

This is the whole point: the command on your laptop and the command in the pipeline are the same orchstep run check. When CI goes red, you reproduce it in one line. Wiring it into your pipeline is one step — see Running in CI.

Forgot the task name? Press a key, not your memory:

orchstep menu

Confirm which backend the build targets

A dry-run resolves every variable and prints the plan, so you can read which api_base the build will use before it runs:

orchstep run preview --dry-run

That turns "I think this build hits staging" into seeing it. More in Previewing with Dry Run.

What you actually gained

ConcernBeforeOrchStep
Reproduce a CI failureread pipeline YAML, guess flagsorchstep run check — same as CI
Which API base?grep .env filesnamed api_base, overridable with --var
Flaky test on slow runnersre-run by handretry: { max_attempts: 2 }
Preview URLcopy from logscaptured as a step output
Ship something untestedeasy to do by accidentpreview calls check first

If your framework's CLI already does all of this in one command, use it. The moment you're chaining four tools with conditional env vars and a deploy, this is the version a teammate can read. And nothing here replaces your bundler — it just stops you from running it with the wrong URL.

Where to go next

Tired of guessing which API a build hit? Run orchstep init and put the answer in the file.

#FRONTEND#CI#PREVIEW#BUILD
Try it in two minutes — one binary, no signup.
curl -fsSL https://orchstep.dev/install.sh | sh

RELATED — BY ROLE