Pkl (pronounced 'pickle') is Apple's new configuration language — type-safe, composable, and generates JSON, YAML, or any format. Replace your brittle YAML with something that actually catches errors.
Why Pkl?
- Type-safe: Catch config errors before deployment
- Composable: Inherit, extend, amend configurations
- Multi-output: Generate JSON, YAML, XML, properties
- IDE support: Autocomplete, go-to-definition
- Validation: Built-in constraints
- Apple-backed: Open source from Apple
Install
# macOS
brew install pkl
# Linux
curl -L https://github.com/apple/pkl/releases/latest/download/pkl-linux-amd64 -o pkl
chmod +x pkl
Basic Config
// config.pkl
name = "my-app"
version = "1.2.3"
server {
host = "0.0.0.0"
port = 8080
maxConnections = 100
}
database {
url = "postgres://localhost:5432/mydb"
pool {
min = 5
max = 20
}
}
Generate JSON:
pkl eval config.pkl -f json
Type Safety
class ServerConfig {
host: String
port: Int(isBetween(1, 65535))
maxConnections: Int(isPositive)
tls: Boolean = false
}
class DatabaseConfig {
url: String
pool: PoolConfig
}
class PoolConfig {
min: Int(isPositive)
max: Int(this >= outer.min) // max must be >= min
}
server: ServerConfig = new {
host = "0.0.0.0"
port = 8080
maxConnections = 100
}
database: DatabaseConfig = new {
url = "postgres://localhost:5432/mydb"
pool = new {
min = 5
max = 20
}
}
Environments (Amend)
// production.pkl
amends "config.pkl"
server {
tls = true
maxConnections = 1000
}
database {
url = "postgres://prod-db:5432/mydb"
pool {
min = 20
max = 100
}
}
Production inherits all defaults, only overrides what changes.
Generate Kubernetes YAML
output {
renderer = new YamlRenderer {}
}
apiVersion = "apps/v1"
kind = "Deployment"
metadata {
name = "my-app"
labels {
["app"] = "my-app"
}
}
spec {
replicas = 3
template {
spec {
containers {
new {
name = "my-app"
image = "my-app:1.2.3"
ports {
new { containerPort = 8080 }
}
}
}
}
}
}
Validation
port: Int(isBetween(1, 65535))
email: String(matches(Regex("^[^@]+@[^@]+\\.[^@]+$")))
replicas: Int(this >= 1 && this <= 100)
memory: DataSize(this >= 256.mb && this <= 16.gb)
Real-World Use Case
A team had 50 YAML files for Kubernetes deployments. A typo in replicas: 30 (should have been 3) caused a $2,000 cloud bill. After switching to Pkl with replicas: Int(this <= 10), such errors are caught at generate time, not in production.
Need to automate data collection? Check out my Apify actors for ready-made scrapers, or email spinov001@gmail.com for custom solutions.
Top comments (0)