ModernCI as an alternative to GitHub Actions
GitHub Actions is a hosted workflow runner with a large action marketplace, hosted Linux, Windows and macOS runners, and GitHub's merge queue. ModernCI is a self-hosted CI server and merge queue. It runs your build and test commands unchanged on your machines or elastic runners, cancels work a newer push made pointless, merges green pull requests on its own, and pushes failures back to coding agents over MCP. Stay on Actions if you depend on marketplace actions, Windows or macOS runners, or a hosted service with nothing to run. Consider ModernCI if your bottleneck is the queue of agent-written pull requests waiting to be tested and merged.
Marks: live is in release 0.4.28 on main; preview is built in an open pull request, not released; planned is decided, not built. GitHub facts are from GitHub's documentation, read 2026-10-13.
When GitHub Actions is the better fit
- You rely on marketplace actions beyond checkout and toolchain setup, on deployment workflows, or on reusable workflows.
- You need Windows or macOS runners. ModernCI's daemon and backends run on Linux and macOS hosts, and there's no Windows support.
- You want a hosted service with no daemon to run. ModernCI is self-hosted only today, and hosted is planned.
- Your pull request volume is low enough that queueing and re-runs aren't your problem.
- You need GitLab as well. ModernCI supports GitHub and Gitea, and GitLab is planned.
When to consider ModernCI
- Coding agents open many pull requests and you want a failure pushed back into the agent's session, not a red check someone has to notice. live
- Pushes arrive faster than runs finish, and you pay for runs a newer push already made pointless. ModernCI cancels them, including across pull requests whose heads contain each other. live
- You want the merge queue to merge the deepest green prefix of a batch and bisect a failing one, and to merge exactly the commit it tested. live
- You want to self-host, or run with no outside service at all (no Actions, no database, no modernci.dev). live
- You want one usage record per check, with cost per merged change computed from them. live
Side by side
| GitHub Actions | ModernCI | |
|---|---|---|
| Where it runs | GitHub-hosted runners, or your self-hosted runners | A daemon you run; checks on your machine, ssh hosts or Latchkey runners live |
| Config | .github/workflows/*.yml, jobs and steps | .ci/<branch>.yaml: your commands as checks, read from the target branch live |
| Concurrency | 20 (Free), 40 (Pro), 60 (Team), 500 (Enterprise) concurrent jobs on standard hosted runners | Whatever your backends accept now; no slot count live |
| Job time limit | 6 hours per job on hosted runners | Per-check deadline you set; a stalled check is stopped and re-run, never reported as a test failure preview PR #83 |
| Linux hosted price | 2-core $0.006/min, 4-core $0.012/min, 8-core $0.022/min | Your machines: no charge from ModernCI. Pricing per merged change is planned and nothing is billed today. |
| Merge queue | GitHub merge queue (merge_group event) | Built in: chained, deepest green prefix merges, k-ary bisect live |
| Stale runs | concurrency: groups cancel per workflow and ref | Per check, by input key, across pull requests live |
| Result reuse | actions/cache keys you write | Reuse by input key: the tree plus declared inputs live |
| Failures to agents | Status checks and logs | Pushed to the author's MCP session with the reproduce command and diff live |
| Windows / macOS jobs | Yes | No Windows; macOS hosts as backends |
| Marketplace actions | Yes | No. The importer maps checkout and toolchain setup and reports the rest |
Migrating
- Import.
modernci import github .github/workflows/*.yml --to main -o .ci/main.yamlwrites one branch file. Every line not carried over is reported with its file and line, and the command exits 1 if any of them could change a result.actions/checkoutand the commonsetup-*toolchain actions are mapped; otheruses:steps are reported. live - Shadow. Register the repo and let ModernCI test pull requests beside Actions without merging. The
shadowop lists each comparison and whether the two agree,shadow_replayre-tests recently merged changes, andexplainrecords why a comparison differs. live - Cut over when the results agree: make ModernCI's status the required check and let it merge.
Running on top of Actions planned
External checks: a ModernCI check answered by your existing CI's statuses on the exact commit ModernCI tests. ModernCI pushes that commit to a modernci/try/… branch, your workflow runs there (one line in its trigger), and the merge queue uses the result. You keep Actions for execution and add ModernCI's queue. This isn't built yet. Until it is, use ModernCI's own checks alongside Actions in shadow.
Evidence
- Cost and pull-request-to-merge time against GitHub Actions on the same repos and runner sizes: measurement in progress. See benchmarks for the method.
- GitHub sources: Actions runner pricing and Actions limits, both read 2026-10-13.
Limitations of ModernCI here
- In 0.4.28 one pull request's checks run one after another. Actions runs jobs in parallel.
- No public download yet, no hosted service, no marketplace.
- Per-test results, flaky-test handling and affected-test selection are Rust-focused (cargo-nextest, libtest, Cargo).
See also: Blacksmith, Namespace, facts.