act
Run GitHub Actions workflows locally for fast feedback
act lets developers run GitHub Actions workflows on their own machine using Docker, providing fast local feedback before pushing. It reads the same workflow files used by GitHub so behavior closely matches CI.
Key features
- Local GitHub Actions runs
- Docker-based execution
- Reuses workflow files
- Fast feedback loop
Pros & cons
Strengths
- Test CI before pushing
- Saves CI minutes
Trade-offs
- Not all actions supported
- Docker required
act replaces
Last reviewed Aug 26, 2026 · 803 words
The average "fix CI" session is ten commits named try again, each costing a 2–5 minute queue-and-boot round trip on GitHub's runners. act deletes that loop: it reads the exact workflow files in .github/workflows and executes the jobs in Docker containers on your machine, so a broken step fails in seconds, locally, with the logs in your terminal. It's a single Go binary, MIT-licensed, 71,634 stars, and it needs roughly 256 MB of RAM plus a working Docker daemon. It is not a full CI server — it's a debugging and pre-push tool, and used that way it pays for itself the first afternoon.
Install is trivial; the image choice is the real decision
The binary installs from your package manager (brew install act, or the install script from the official docs). On first run act asks which default runner image to use, and this choice matters more than anything else in setup. Micro is a few hundred MB and has Node.js plus almost nothing else — fine for pure-JavaScript actions, guaranteed to break on anything that expects a real Ubuntu toolchain. Medium (the catthehacker/ubuntu images) is around 1 GB and covers most real-world workflows; it's the sensible default. Large aims for parity with GitHub's actual runner image and is a download measured in tens of GB — install it only when a workflow's failure genuinely traces to missing preinstalled tooling. Start with medium; escalate on evidence.
Four commands cover ninety percent of use
act -l # list jobs act can see
act # simulate a push event, run its jobs
act pull_request # simulate a PR event instead
act -j test -s GITHUB_TOKEN="$(gh auth token)" # one job, with a secret
Secrets never come from GitHub — pass them with -s NAME=value or keep a --secret-file outside version control. Flags you use every time belong in an .actrc file in the repo or your home directory. The -j flag is the workhorse: when one job in a six-job workflow is failing, you iterate on that job alone instead of re-running the world.
Know where the emulation ends
act's fidelity is good, not perfect, and the gaps are predictable. Everything runs in Linux containers, so runs-on: macos- and windows- jobs get mapped onto Linux images — a compile check might pass, but anything OS-specific is untested. GITHUB_TOKEN isn't provided automatically; actions that call the GitHub API need a real token passed as a secret, as above. Actions that lean on GitHub's preinstalled tool cache or runner-specific services are the other classic breakage, which is the honest reading of the catalogue's "not all actions supported" warning. My rule: a green act run means push with confidence; a red act run means fix before pushing; a red act run on an exotic action means five minutes of checking whether act or the workflow is at fault before touching anything.
The same engine can run your self-hosted forge's CI
act has a second life beyond local debugging: it is the execution engine inside the act_runner that powers Actions on Gitea and Forgejo. That makes workflow knowledge portable — the YAML you debug locally with act is the same format your self-hosted forge executes, so moving off github.com doesn't mean rewriting CI. If what you actually want is a standing CI server rather than local execution, that forge-plus-runner combination, or a dedicated system from the CI/CD category, is the right shape; act itself deliberately stays a client-side tool with no daemon, no queue, and no web UI.
What it saves in real numbers
GitHub's free tier gives private repos 2,000 Actions minutes a month, and a fumbled debugging session can burn 100+ of them on failed runs. act moves that spend to your own CPU, where iteration is also faster: no queue time, no runner boot, cached Docker layers between runs. For public repos the minutes are free anyway — there the win is purely the feedback loop, which drops from minutes to seconds per attempt.
What I'd do
Install act the day a repo gets its second workflow file. Pick the medium image, commit an .actrc with your platform mappings, put real secrets in a git-ignored secret file, and make act -j <job> your reflex before any push that touches CI. Keep expectations calibrated — it's a pre-flight check, not a bit-perfect GitHub clone — and let the runs that must be authoritative happen on GitHub. If you're self-hosting your git anyway, the Gitea/Forgejo act_runner route means the same workflows run at home, and act on your laptop debugs both.
Compare act
5 head-to-head comparisons.
Similar ci/cd & build apps
Drone
CI/CD & BuildContainer-based continuous delivery platform
Replaces Jenkins, CircleCI
Jenkins
CI/CD & BuildExtensible open-source automation server for CI/CD
Replaces CircleCI
Argo CD
CI/CD & BuildDeclarative GitOps continuous delivery for Kubernetes
Replaces Spinnaker
Argo Workflows
CI/CD & BuildContainer-native workflow engine for Kubernetes
Replaces Airflow
Dagger
CI/CD & BuildProgrammable CI/CD engine that runs pipelines as code
Replaces GitHub Actions, CircleCI
Bytebase
CI/CD & BuildDatabase DevOps and CI/CD for schema changes
Replaces Liquibase, Flyway