Source: https://www.kcl-lang.io/docs/user_docs/getting-started/
GitHub: https://github.com/kcl-lang/kcl
Core Idea
KCL is a CNCF config and policy language (Python-flavored, statically typed, compiled with Rust/LLVM) that outputs YAML and fixes the pain of scaling raw Kubernetes manifests.
- Problems it targets: dimension explosion (a file per environment), configuration drift without standards, and cognitive overload from low-level Kubernetes YAML.
- Core ideas: schemas as types, constraints and rules as policies, automatic merge of isolated config blocks, and output as YAML by default.
- Ecosystem: plugins for Kustomize, Helm, KPT, kubectl, and Crossplane, plus multi-language SDKs; production use noted at Ant Group.
1. What is KCL?
KCL (originally Kube Configuration Language) is an open-source, cloud-native configuration and policy language hosted by the Cloud Native Computing Foundation (CNCF) as a Sandbox Project.
- Inspired by Python 3 in syntax
- Incorporates declarative and OOP programming paradigms
- Built on constraints and functional programming principles
- Compiled and statically typed
- Core elements: configurations, schemas, lambdas (functions), and rules (policies)
- Output format: YAML (and other structured formats)
KCL is not a general-purpose language β it is deliberately scoped to configuration and policy authoring in cloud-native environments.
2. Why KCL? β Problems It Solves
KCL addresses three core pain points in large-scale configuration management:
| Problem | Description |
|---|---|
| Dimension Explosion | Static configs like Kubernetes YAML require separate files per environment, leading to hard-to-debug errors at scale |
| Configuration Drift | Managing dynamic configs across environments without standards leads to ad-hoc scripting and inconsistency |
| Cognitive Overload | Low-level platforms like Kubernetes lack higher-level abstractions, burdening developers |
Solutions KCL Provides
- API abstractions β hides infrastructure complexity behind clean interfaces
- Mutation & validation β modify and verify existing config files/manifests programmatically
- Large-scale automation β consistent management across teams without unintended side effects
3. Key Characteristics
| Trait | Detail |
|---|---|
| Easy-to-use | Python/Go-inspired syntax; functional with minimal side effects |
| Well-designed | Spec-driven syntax, semantics, and runtime |
| Quick modeling | Schema-centric types with modular abstraction |
| Stable | Built on static type system, constraints, and rules |
| Scalable | Automatic merge mechanism for isolated config blocks |
| Fast automation | CRUD APIs, multi-language APIs, language plugins |
| High performance | Built with Rust, C, and LLVM; compiles to native code and WebAssembly |
| API affinity | Native support for JsonSchema, OpenAPI, Kubernetes CRDs, Terraform schemas |
| Dev-friendly | Rich IDE extensions (VS Code), format/lint/test/vet/doc tools |
| Safe | Domain-scoped β no system-level I/O, threading, or infinite loops |
| Multi-language SDK | Rust, Go, Python, Java, .NET, Node.js, Kotlin, Swift, C, C++, WASM, REST |
| K8s integration | Plugins for Kustomize, Helm, KPT, kubectl, Crossplane |
| Production-ready | Deployed at Ant Group for platform engineering |
4. Core Language Concepts
4.1 Hello KCL
The simplest possible KCL program β hello.k:
hello = "KCL"Run it: kcl hello.k
Output (YAML): hello: KCL
KCL programs always output YAML by default.
4.2 Complex Configurations
KCL supports nested dictionaries, lists, booleans, numerics, and strings.
# Example: server.k
# This is a KCL document
title = "KCL Example"
owner = {
name = "The KCL Authors"
data = "2020-01-02T03:04:05"
}
database = {
enabled = True
ports = [8000, 8001, 8002]
data = [["delta", "phi"], [3.14]]
temp_targets = {cpu = 79.5, case = 72.0}
}
servers = [
{ip = "10.0.0.1", role = "frontend"}
{ip = "10.0.0.2", role = "backend"}
]YAML output:
title: KCL Example
owner:
name: The KCL Authors
data: "2020-01-02T03:04:05"
database:
enabled: true
ports:
- 8000
- 8001
- 8002
data:
- - delta
- phi
- - 3.14
temp_targets:
cpu: 79.5
case: 72.0
servers:
- ip: 10.0.0.1
role: frontend
- ip: 10.0.0.2
role: backendSyntax notes:
#β line comment{}β dictionary (key-value pairs)[]β listTrue/Falseβ boolean literals- Dictionaries and lists can be nested arbitrarily
4.3 Schema β Typed Structures
schema is KCLβs core abstraction mechanism. It defines a typed structure with optional default values.
Defining a Schema
schema DatabaseConfig:
enabled: bool = True
ports: [int] = [8000, 8001, 8002]
data: [[str|float]] = [["delta", "phi"], [3.14]]
temp_targets: {str: float} = {cpu = 79.5, case = 72.0}Using a Schema (with defaults)
database = DatabaseConfig {}Overriding Default Values
database = DatabaseConfig {
ports = [2020, 2021]
}Type Errors Are Caught at Compile Time
# This will fail:
database = DatabaseConfig {
ports = [1.2, 1.3] # Wrong! Expected [int], got [float]
}Error output:
error[E2G22]: TypeError
--> /path/to/server.k:8:5
|
8 | ports = [1.2, 1.3]
| ^ expected [int], got [float(1.2)|float(1.3)]Enum / Union Types in Schema
schema ServerConfig:
ip: str
role: "frontend" | "backend"
servers = [
ServerConfig {ip = "10.0.0.1", role = "frontend"}
ServerConfig {ip = "10.0.0.2", role = "backend"}
]ipis required (no default) β omitting it causes a missing-attribute errorroleis a string union type (enum-like)
Schema Can Also Use
checkblocks β for custom constraint validationmixinβ for composable behavior- Optional attributes (
?) - Inheritance (single)
- External module imports
5. Attribute Configuration Pattern
Every KCL attribute follows this general pattern:
k o (T) v
| Symbol | Meaning |
|---|---|
k | Attribute name |
o | Attribute operator (e.g., =) |
T | Type annotation (optional β KCL infers types) |
v | Attribute value |
Example:
deploy = Deployment {}Since KCL supports type inference, the type annotation T is usually omitted.
6. Real-World Example: Kubernetes Manifest
KCL can generate Kubernetes manifests directly:
apiVersion = "apps/v1"
kind = "Deployment"
metadata = {
name = "nginx"
labels.app = name
}
spec = {
replicas = 3
selector.matchLabels = metadata.labels
template.metadata.labels = metadata.labels
template.spec.containers = [
{
name = metadata.name
image = "${metadata.name}:1.14.2"
ports = [{ containerPort = 80 }]
}
]
}Generated YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 807. Ecosystem & Tooling
Language Tools (built-in)
kcl formatβ auto-format KCL codekcl lintβ lint checkskcl testβ run testskcl vetβ validate configs (e.g., against Terraform plan files)kcl docβ generate documentation
IDE Support
- VS Code extension
- NeoVim plugin
- Playground at http://play.kcl-lang.io/
Package Management
- Module sharing via OCI registries
- Browse modules at https://artifacthub.io/packages/search?org=kcl
Kubernetes Integrations
| Tool | Purpose |
|---|---|
| Kustomize KCL Plugin | Mutate/validate Kustomize resources |
| Helm KCL Plugin | Extend existing Helm charts |
| KPT KCL SDK | Use with KPT workflows |
| Kubectl KCL Plugin | Apply KCL transforms via kubectl |
| Crossplane KCL Function | Use in Crossplane compositions |
Multi-Language SDKs
Go, Python, Rust, Java, .NET, Node.js, Kotlin, Swift, C, C++, WASM, REST
8. KCL vs. Other Tools
| Tool | Use Instead When⦠|
|---|---|
| YAML/JSON | Small-scale, simple key-value configs; Kubernetes native tooling |
| Kustomize | Simple overlay-based Kubernetes config management |
| Helm | Package management for Kubernetes β KCL can extend Helm charts |
| HCL (Terraform) | Good human-readable configs for infra; already in Terraform |
| CUE | Type-system-driven config; KCL is faster at scale and more expressive |
| Jsonnet/GCL | Code-generated configs, but KCL has better type checking and performance |
| Dhall | Functional config; KCL is more OO-friendly and has better tooling |
| Starlark | Bazel build configs β KCL adds static typing and compilation |
| Pkl | Similar features, but KCL has deeper cloud-native integrations |
| OPA/Rego | Policy enforcement; KCL is better for data definition + constraint modeling |
| CDK | App-level infrastructure code; KCL decouples config from client runtime |
When to Choose KCL
- You need types and modeling like a modern language
- You manage large-scale, multi-environment configurations
- You want pure functions and declarative rules in-house
- You need production-grade performance and automation
- Youβre working in cloud-native / Kubernetes environments
9. When to Use KCL
Use KCL if you want:
β
Typed, validated configuration (not just YAML)
β
Reusable schemas and abstractions
β
Large-scale config across teams/environments
β
Kubernetes manifest generation
β
Automated config mutation/validation pipelines
β
Integration with Helm, Kustomize, Terraform, OCI
Avoid KCL if you need:
β A general-purpose programming language
β System I/O or threading
β Very simple, small-scale configs (plain YAML is fine)
10. Quick Reference: Type System
| Type Syntax | Meaning |
|---|---|
str | String |
int | Integer |
float | Float |
bool | Boolean |
[int] | List of integers |
{str: float} | Dict with string keys and float values |
[[str|float]] | List of lists, inner elements are str or float |
"frontend" | "backend" | String union (enum) |
str? | Optional string attribute |
11. Links & Resources
| Resource | URL |
|---|---|
| Official Docs | https://www.kcl-lang.io/docs/user_docs/getting-started/ |
| GitHub | https://github.com/kcl-lang/kcl |
| Playground | http://play.kcl-lang.io/ |
| Language Tour (full reference) | https://www.kcl-lang.io/docs/reference/lang/tour |
| Module Registry | https://artifacthub.io/packages/search?org=kcl |
| Examples | https://github.com/kcl-lang/examples |
| Community | https://www.kcl-lang.io/docs/community/intro/ |
| Blog | https://www.kcl-lang.io/blog |
| KusionStack (related project) | https://kusionstack.io |