helm‑schema

Generate a JSON Schema for a Helm chart's values.yaml by analyzing the chart's templates — not by guessing from the defaults file. Open source, MIT-licensed.

helm-schema ./mychart

build status test status crates.io docs.rs

A chart’s values.yaml is a documented default, not a contract. It says what a value is set to, never what it must be — a port that happens to be 80 could be typed as a string, an object, or anything else. helm-schema recovers the real contract by reading the templates: it follows each .Values.* into the resource field it renders, and types it from what Kubernetes expects there.

templates/deployment.yamlchart
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: {{ .Values.replicaCount }}
  revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
values.schema.jsongenerated
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "additionalProperties": false,
  "properties": {
    "replicaCount": {
      "anyOf": [
        {
          "description": "Number of desired pods. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1.",
          "format": "int32",
          "type": "integer"
        },
        {
          "pattern": "^(([+-]_*)?(0|[1-9][0-9_]{0,17}|0[xX][0-9a-fA-F]{1,15}|0[bB][01]{1,62}|0[oO][0-7]{1,20}|0[0-7]{1,20})|[+-]?0[0-7]{0,8}[89][0-9]{0,8})$",
          "type": "string"
        }
      ]
    },
    "revisionHistoryLimit": {
      "anyOf": [
        {
          "description": "The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 10.",
          "format": "int32",
          "type": "integer"
        },
        {
          "pattern": "^(([+-]_*)?(0|[1-9][0-9_]{0,17}|0[xX][0-9a-fA-F]{1,15}|0[bB][01]{1,62}|0[oO][0-7]{1,20}|0[0-7]{1,20})|[+-]?0[0-7]{0,8}[89][0-9]{0,8})$",
          "type": "string"
        }
      ]
    }
  },
  "type": "object",
  "x-helm-schema-generated": true
}

replicaCount lands in a Deployment’s spec.replicas, so it is typed as an int32 and annotated with Kubernetes’ own field description — recovered from the template, never stated in values.yaml. (The second arm covers Helm’s quoted-number form, e.g. "1".)

What it does#

Template-aware

Parses Helm templates and statically extracts every .Values.* path from the actual render logic — not from the defaults file.

Control-flow aware

Understands if, with, range, and patterns like eq, not, or, and default, so the schema mirrors the template's real logic.

Resource-aware

Tracks which Kubernetes resource and field a value flows into, so it can type the value against the upstream API.

Schema-backed

Types values from upstream Kubernetes JSON schemas and CRD catalogs, and merges everything into one Draft-07 schema.

Get started#

# Install the CLI (or: brew install --cask romnn/tap/helm-schema)
cargo install --locked helm-schema-cli

# Generate a schema for a chart directory
helm-schema ./mychart --output mychart/values.schema.json

Helm picks up a values.schema.json next to values.yaml automatically and validates user-supplied values against it on install, upgrade, lint, and template.

Documentation#