by redwoodjs
Run GitHub Actions locally — pause on failure, retry in place, and keep caches on your machine.
# Add to your Claude Code skills
git clone https://github.com/redwoodjs/local-ciLast scanned: 8/7/2026
{
"issues": [
{
"file": "CLAUDE.md",
"line": 11,
"type": "prompt-injection",
"message": "Possible concealment directive: \"Do not tell the user\"",
"severity": "medium"
}
],
"status": "PASSED",
"scannedAt": "2026-08-07T05:39:37.003Z",
"npmAuditRan": true,
"pipAuditRan": true,
"promptInjectionRan": true
}local-ci is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by redwoodjs. Run GitHub Actions locally — pause on failure, retry in place, and keep caches on your machine. It has 726 GitHub stars.
Yes. local-ci passed SkillsLLM's automated security scan — a dependency vulnerability audit plus prompt-injection heuristics — with no high-severity issues. You can read the full report in the Security Report section on this page.
Clone the repository with "git clone https://github.com/redwoodjs/local-ci" and add it to your Claude Code skills directory (see the Installation section above).
local-ci is primarily written in TypeScript. It is open-source under redwoodjs on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh local-ci against similar tools.
No comments yet. Be the first to share your thoughts!
Run GitHub Actions on your machine. Caching in ~0 ms. Pause on failure. Fix and retry — before you commit, before you push.
Local CI is a ground-up rewrite of the GitHub Actions orchestration layer that runs entirely on your own machine. It doesn't wrap or shim the runner: it replaces the cloud API that the official GitHub Actions Runner talks to, so the same runner binary that executes your jobs on GitHub.com executes them locally, bit-for-bit.
Actions like actions/checkout, actions/setup-node, and actions/cache work out of the box — no patches, no forks, no network calls to GitHub. Dependencies that took a couple of minutes to install on GitHub's runners install in a few seconds on the second run because package-manager caches stay local and completed dependency trees can be cloned from immutable snapshots.
Remote CI is the final gatekeeper — it runs on every push and decides what ships. That's its job. The problem is what happens when it fails: you push, you wait, you read logs, you push again. Every retry pays the full cost of a fresh run, and the gatekeeper ends up being used as a debugger.
Local CI is a pre-flight check that runs on your own machine before you commit. Catch the failure in seconds, fix it locally, only push work that's already green — and let remote CI stay the gatekeeper.
Existing "run actions locally" tools either re-implement steps in a compatibility layer or require you to maintain a separate config. Local CI does neither.
| GitHub Actions | Other local runners | Local CI | |
|---|---|---|---|
| Runner binary | Official | Custom re-implementation | Official |
| API layer | GitHub.com | Compatibility shim | Full local emulation |
| Cache round-trip | Network (~seconds) | Varies | ~0 ms (local filesystem) |
| On failure | Start over | Start over | Pause → fix → retry the failed step |
| Container state on failure | Destroyed | Destroyed | Kept alive |
| Requires a clean commit | Yes | Yes | No — runs against working tree |
Local CI replaces GitHub's cloud cache with local filesystem caches. Package-manager stores, Playwright browsers, and the runner tool cache live on the host with no upload or download round-trip. Every job gets private writable node_modules; pnpm, Yarn, and Bun jobs can start from an immutable lockfile-keyed snapshot cloned with copy-on-write when the host supports it. npm jobs share npm's download cache because npm ci removes node_modules by design.
For workflows with several independent jobs, use --prewarm-through <workflow:job:step-id> to populate the dependency cache once before the real jobs start in parallel. The selected step must have a stable id. Local CI runs a disposable copy of that job from the beginning through the selected step, atomically publishes a completed snapshot, and clones it into each real job's private workspace. You can also set LOCAL_CI_PREWARM_THROUGH in .env.local-ci to make this automatic for a repo. Without explicit prewarming, jobs remain isolated and safe; the first successful job can populate the cache for later runs.
Step 6 failed. Fix the file. Retry just that step. Green. No checkout, no reinstall, no waiting.
When a step fails, Local CI pauses instead of tearing down. The container stays alive with all state intact — environment variables, installed tools, intermediate build artifacts. Your edits on the host are synced into the container, so you (or your AI agent) can fix the issue and retry just the failed step.
Local CI does not re-implement GitHub Actions. It emulates the server-side API surface — the Twirp endpoints, the Azure Block Blob artifact protocol, the cache REST API — and feeds jobs to the unmodified, official runner. If your workflow runs on GitHub, it runs here.
Docker — a running Docker provider:
Optional — for runs-on: macos-* jobs (Apple Silicon Macs only):
brew install cirruslabs/cli/tartsshpass — brew install hudochenkov/sshpass/sshpassWithout both, macOS jobs are skipped with a reason. See macOS jobs below.
# Run a specific workflow
npx run-local-ci run --workflow .github/workflows/ci.yml
# Run all relevant workflows for the current branch
npx run-local-ci run --all
Local CI runs against your current working tree — uncommitted changes are included automatically. No need to commit or stash before running.
Agent CI is now Local CI. Install and invoke the canonical package with npx run-local-ci; the executable installed into node_modules/.bin is local-ci.
Existing @redwoodjs/agent-ci installations continue to work throughout the remaining 0.x releases. The compatibility package forwards the agent-ci executable to Local CI. Existing AGENT_CI_* environment variables, .env.agent-ci, .github/agent-ci.Dockerfile, and legacy Agent CI Docker resources are also recognized. New configuration should use LOCAL_CI_*, .env.local-ci, and .github/local-ci.Dockerfile.
Committing is optional, but it's a useful pattern: commit → run → fail → fix with --pause-on-failure → retry → commit the fix. When you do commit, the commit becomes a save point you can return to if the fix makes things worse. Your AI agent benefits from the same pattern — it can roll back to a known-good state before trying a different fix.
The npm package keeps npx run-local-ci on the TypeScript execution path. The Rust runner is available in this repository for parity testing, but published npm installs do not include a native runner yet. Native npm platform packages and release archives are deferred until the release workflow builds, stages, and verifies real target binaries.
To try the Rust runner from a checkout, build or run it directly with Cargo:
cargo run -p local-ci -- run --workflow .github/workflows/ci.yml
# or
cargo build --release -p local-ci
./target/release/local-ci run --workflow .github/workflows/ci.yml
The development wrapper can also build and run the Rust binary from a checkout:
LOCAL_CI_FORCE_RUST=1 pnpm local-ci-dev run --workflow .github/workflows/ci.yml
For published npm installs, LOCAL_CI_FORCE_RUST=1 npx run-local-ci ... is expected to fail until native binary packaging lands. To force the TypeScript path explicitly, run with LOCAL_CI_FORCE_TYPESCRIPT=1 or LOCAL_CI_FORCE_TS=1.
npx run-local-ci retry --name <runner-name>
local-ci runRun GitHub Actions workflow jobs locally.
| Flag | Short | Description |
|---|---|---|
--workflow <path> |
-w |
Path to the workflow file |
--all |
-a |
Discover and run all relevant workflows for the current branch |
--pause-on-failure |
-p |
Pause on step failure for interactive debugging |
--quiet |
-q |
Suppress animated rendering (also enabled by AI_AGENT=1) |
--json |
Emit NDJSON event stream on stdout (also enabled by LOCAL_CI_JSON=1); see Agent output mode |
|
--no-matrix |
Collapse all matrix combinations into a single job (uses first value of each key) | |
--jobs <N> |
-j |
Maximum jobs to run at once |