KiCI

KiCI vs GitLab CI/CD

A point-by-point look at KiCI — typed-TypeScript pipelines on infrastructure you control, with a managed control plane you never operate — versus GitLab CI/CD, whether on GitLab.com or a fully self-managed GitLab you run yourself.

Visit GitLab CI/CD homepage ↗

KiCI GitLab CI/CD
Workflow language
Pipelines are real, typed TypeScript — loops, conditionals, functions, autocomplete
Pipelines are configured in a .gitlab-ci.yml YAML file at the root of the project
Source code and secrets
Your source and secrets stay on your own sovereign infrastructure; KiCI’s hosted control plane never receives them
CI/CD variables — including secrets — are added to and stored in your GitLab project, group, or instance settings
Self-hosting model
You self-host only the execution — orchestrator and agents — while KiCI runs the control plane as a managed service, so your code stays sovereign and there is no platform for you to operate
GitLab is fully self-hostable — you can install and run the entire platform yourself on Linux, cloud providers, or Kubernetes (or use GitLab.com SaaS)
Autoscaling ephemeral agents
A built-in auto-scaler provisions ephemeral agents on demand across Docker/Podman containers, bare-metal processes, and Firecracker microVMs — on your own infrastructure, with no extra controller
GitLab Runner autoscaling spins up cloud instances on demand through a separate runner manager you configure
Cost model
The hosted control plane is free with full functionality; paid tiers raise observability and usage limits (retention, members, orchestrators) for scale and experience — they never meter your executions, so the cost never grows with how much CI you run. You provide the execution compute itself.
GitLab-hosted (instance) runner usage is metered in compute minutes; self-managed runners run on infrastructure you provide
Development experience
Testing & local dev loop
kici run --local and kici run remote trigger a workflow straight from your current codebase — including unstaged changes — so you get a result without committing or pushing
Pipelines run when you push a commit or open a merge request, so trying a change means pushing it to GitLab and waiting for the pipeline before you can see the result
Dynamic job generation
Generate jobs programmatically at runtime — a dynamicJob generator emits job definitions in TypeScript, fanning out one job per item an upstream job discovers (beyond static and dynamic matrices)
Dynamic behavior is via child pipelines — a job generates a YAML config file at runtime and triggers it as a child pipeline
Typed values between steps & jobs
Step and job outputs are declared with Zod schemas, so values passed between jobs are typed and validated — not stringly-typed
Values flow between jobs as dotenv environment variables — plain string CI/CD variables, with no schema validation
Get started with KiCI See all comparisons