CUE (Configure, Unify, Execute) is a language by a former Google engineer designed to validate, generate, and transform structured data. Think of it as JSON Schema on steroids with a proper type system.
Why CUE Matters
YAML and JSON have no built-in validation. You write a Kubernetes manifest, deploy it, and only discover typos in production. CUE catches these at authoring time with constraints that compose and scale.
What you get for free:
- Validate any data format: JSON, YAML, Protobuf, OpenAPI
- Types ARE values — no separate schema language
- Constraints compose automatically
- Built-in Kubernetes, Terraform, and OpenAPI support
- Generate OpenAPI schemas from CUE definitions
- cue fmt — automatic formatting like gofmt
- Go API for embedding in applications
Quick Start
# Install
go install cuelang.org/go/cmd/cue@latest
# Validate YAML against CUE schema
cue vet schema.cue data.yaml
# Export CUE to JSON
cue export config.cue
# Export to YAML
cue export config.cue --out yaml
# Format CUE files
cue fmt
Basic Constraints
// schema.cue — define what valid data looks like
name: string & =~"^[a-zA-Z]+$" // Must be letters only
age: int & >0 & <150 // Must be positive, under 150
email: string & =~"@" // Must contain @
role: "admin" | "user" | "guest" // Must be one of these
active: bool | *true // Default: true
// Nested structures
address: {
street: string
city: string
zip: string & =~"^[0-9]{5}$" // 5-digit zip
country: string & strings.MinRunes(2)
}
# data.yaml — this gets validated against schema.cue
name: Alice
age: 30
email: alice@example.com
role: admin
address:
street: "123 Main St"
city: "Springfield"
zip: "12345"
country: "US"
Kubernetes Validation
package k8s
#Deployment: {
apiVersion: "apps/v1"
kind: "Deployment"
metadata: {
name: string & =~"^[a-z][a-z0-9-]+$"
namespace: string | *"default"
labels: [string]: string
}
spec: {
replicas: int & >0 & <=100
selector: matchLabels: [string]: string
template: {
metadata: labels: [string]: string
spec: containers: [...#Container]
}
}
}
#Container: {
name: string
image: string & =~":" // Must include tag
ports: [...{
containerPort: int & >0 & <=65535
protocol: "TCP" | "UDP" | *"TCP"
}]
resources: {
requests: {
cpu: string
memory: string
}
limits: {
cpu: string
memory: string
}
}
}
// Actual deployment — validated against schema
webApp: #Deployment & {
metadata: {
name: "web-app"
labels: app: "web"
}
spec: {
replicas: 3
selector: matchLabels: app: "web"
template: {
metadata: labels: app: "web"
spec: containers: [{
name: "web"
image: "myregistry/web:v2.1.0"
ports: [{containerPort: 8080}]
resources: {
requests: { cpu: "100m", memory: "128Mi" }
limits: { cpu: "500m", memory: "512Mi" }
}
}]
}
}
}
Generate OpenAPI Schema
package api
#User: {
id: int
name: string & strings.MinRunes(1)
email: string & =~"^[^@]+@[^@]+$"
role: "admin" | "user"
createdAt: string // ISO 8601
}
#CreateUserRequest: {
name: #User.name
email: #User.email
role: #User.role | *"user"
}
#UserResponse: {
data: #User
error: null | string
}
# Generate OpenAPI 3.0 schema
cue export api.cue --out openapi
Terraform Validation
package terraform
#AWSInstance: {
resource: aws_instance: [string]: {
ami: string & =~"^ami-"
instance_type: "t3.micro" | "t3.small" | "t3.medium" | "t3.large"
tags: {
Name: string
Environment: "dev" | "staging" | "prod"
ManagedBy: "terraform"
}
}
}
Useful Links
Building validated data pipelines? Check out my developer tools on Apify for ready-made web scrapers, or email spinov001@gmail.com for custom solutions.
Top comments (0)