cd /news/developer-tools/show-hn-localci-run-your-github-acti… · home › topics › developer-tools › article
[ARTICLE · art-149043] src=github.com ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

Show HN: Localci, run your GitHub Actions jobs locally before you push

Localci, a new open-source tool from developer peters, runs existing GitHub Actions workflows locally before pushing, cutting a Horizon Rust workspace CI run from a median 27 minutes on GitHub to 2 minutes 16 seconds with `localci run --fast`, according to measurements taken 10-11 October 2026. The tool reads existing `.github/workflows/ci.yml` files with no new config, runs jobs whose `runs-on` matches the local OS, and ships as a single static binary under 800 KB installed in under 2 seconds. Across the last 40 merged Horizon pull requests, large PRs (more than 10 files) averaged 5 review rounds and 5 CI runs at 307 runner-minutes, which the author estimates drops to 1-2 rounds and 60-125 runner-minutes with localci's PR loop.

read7 min views1 publishedOct 11, 2026
Show HN: Localci, run your GitHub Actions jobs locally before you push
Image: Michielbdejong (auto-discovered)

Waiting for GitHub to pick up your push, queue a runner and rebuild everything from a cold cache is slow. Sometimes GitHub is just down. localci runs your existing .github/workflows/ci.yml on your own machine, in seconds, with your build cache still warm.

  • No new config. It reads the workflows you already have.
  • Your OS, your jobs. It runs the jobs whoseruns-on matches your machine (Linux, macOS or Windows) and tells you which ones need another OS.
  • Real steps. Shell steps, matrices,needs , outputs,GITHUB_ENV ,if: conditions andservices: (as Docker containers) behave like they do on GitHub. Setup actions such asactions/checkout are skipped, because your machine already has the checkout and the tools.
  • Made for agents. One command teaches Claude Code, Codex and other agents to run the right subset of your CI before they push.
  • Tiny. One static binary, under 800 KB to download, installed in under 2 seconds.

Measured on Horizon, a public Rust workspace with a Linux, macOS and Windows CI matrix, on 10 and 11 October 2026.

Waiting for GitHub vs. checking locally

Time
One GitHub CI run, push to result (median of 18 runs) 27 minutes
Same Linux jobs with localci run , one after another 15 to 23 minutes
Same change with localci run --fast 2 minutes 16 seconds
localci run --fast again, nothing changed 0 seconds
A failing CI test, found by localci run repo-checks before any push 4 seconds
One code review round with Copilot on the PR, plus a push about 5 minutes
One local review round (the skill's Copilot CLI prompt), no push 1 to 4 minutes

What it saves on a pull request. Without localci, every push starts a full CI run of about 62 runner-minutes, and a fix round waits for it. In the last 40 merged Horizon PRs:

Review rounds CI runs Runner time
Small PRs (5 files or fewer), median 1 1 63 min
Large PRs (more than 10 files), median 5 5 307 min
Large PR with localci and the skill's PR loop (estimate) 1 to 2 1 to 2 60 to 125 min

With the PR loop, you review and test locally until both are clean, and the review on GitHub becomes a final check instead of the place where you iterate. For a large PR that is about 1½ hours less waiting and 3 to 4 hours less runner time. The large-PR row is an estimate; the rows below are measured.

Real PRs, as the loop improved

PR What was new Review rounds on GitHub CI runs Open to ready
#1461 localci before each push, fixes pushed without a CI run 4 (1 with findings) 2 for 4 pushes first approval after 9 min
#1466 a general local review before the PR 5 4 started for 5 pushes 42 min
#1471 a local review that asks for concrete failing inputs, and GitHub's review as the final check 1 1 12 min

For comparison, the median small Horizon PR before localci took 24 minutes from opening to merge, with one review round and one CI run of 63 runner-minutes.

macOS and Linux

curl -fsSL https://raw.githubusercontent.com/peters/localci/main/install.sh | sh

Windows (PowerShell)

irm https://raw.githubusercontent.com/peters/localci/main/install.ps1 | iex

Prefer not to pipe a script into your shell? Download a binary from Releases: Linux x64 and arm64 (static), macOS Apple silicon and Intel, and Windows x64. With Rust installed you can also build it yourself in about 10 seconds: cargo install --locked --git https://github.com/peters/localci.

Then, in any repository with GitHub Actions:

localci list     # every job and matrix leg, and which run here
localci run      # run them
localci skill install

This puts a skill into ~/.claude/skills, ~/.codex/skills and ~/.agents/skills (for each agent you have). From then on, just ask:

Run CI locally before you push.

The agent looks at the plan and your diff, suggests which jobs and steps are worth running, asks you once, runs them, and reads only the log of a step that failed. It knows that a local run is a fast pre-check and not the real GitHub result.

localci plan                          # what would run, step by step, without running it
localci run clippy                    # one job, by id
localci run "linux x64 libs"          # one matrix leg, by name
localci run --matrix shard=libs       # legs with that matrix value
localci run --skip-setup              # leave out apt-get, brew and installer steps
localci run --skip "slow tests"       # leave out steps by name or command
localci run --only lint               # run only matching steps
localci run -k                        # keep going after a failing job
localci run -w release                # another workflow file
localci check                         # can localci handle every workflow here?

Add --json -q for a machine-readable report. Each step's log is kept, and the path is printed at the end.

localci run --fast

--fast is three things at once:

  • --affected : leave out build and test steps (Cargo, npm, dotnet, Go, Gradle, Swift) when none of their inputs changed since your branch left the default branch. A step whose commands localci cannot read always runs.
  • --cache : reuse a step that already passed on the same inputs, including its outputs.
  • --parallel 0 : run independent jobs at the same time (2 to 4, from the CPU count).

On Horizon, a documentation and CI change went from a 23-minute full Linux run to 136 seconds with --fast, and to 0 seconds for a second run with no changes. localci plan --affected shows why each step runs or not. Run once without --fast before you push for review.

Some steps should never run on your laptop, like sudo apt-get install or a deploy job. Mark them with a normal GitHub condition. localci sets LOCALCI, and on GitHub it is empty, so GitHub keeps running them:

jobs:
  deploy:
    if: ${{ !vars.LOCALCI }}          # jobs: use vars
    ...
  test:
    steps:
      - name: Install system packages
        if: ${{ !env.LOCALCI }}       # steps: env or vars
        run: sudo apt-get install -y libssl-dev

Jobs with services: (PostgreSQL, Redis and so on) get real Docker containers with their health checks and port mappings, removed when the job ends. If you already run those services yourself, add --no-services. Set LOCALCI_DOCKER=podman to use Podman.

act is the well-known tool for this, and wrkflw is a newer one. Both try to reproduce a GitHub runner: by default they run each job in a container, and they run uses: actions. That is the right choice when you want to test the workflow itself.

localci answers a different question: "will my change pass CI?" So it makes the opposite choices:

act / wrkflw (default) localci
Where steps run A container that imitates the runner image Your machine, in your checkout
Build cache Usually cold: ignored build output stays outside the container Your warm target/ ,node_modules/ and so on
uses: actions Runs them Skips them; your machine has the tools already
Unchanged steps Run again --fast leaves them out or reuses the result
Agents Not a focus A plan as JSON, a skill, and failing-step logs only

act can also run directly on the host (-P ubuntu-latest=-self-hosted). The difference that remains is what localci leaves out, and that it is built to be driven by an agent.

  • Your CI is mostly marketplace actions. If the real work happens inuses: steps (for exampledocker/build-push-action or a deploy action), localci skips it. Use act, or GitHub.
  • You need the exact runner image. localci uses your tools and versions. A step can pass here and fail on GitHub because a tool differs.
  • Jobs for another OS. It runs only the jobs that match your machine. Run it on that machine instead.
  • Reusable workflows and container: jobs. It does not run them.
  • Results on GitHub. It does not post checks or statuses. GitHub CI stays the final word.

The compatibility table lists every feature, and the decision records explain why.

Every bug becomes a small folder in tests/cases/: a workflow and the result it should give. No Rust code needed. See the procedure, and please open an issue or a pull request.

MIT

── more in #developer-tools 4 stories · sorted by recency
── more on @localci 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/show-hn-localci-run-…] indexed:0 read:7min 2026-10-11 · —