YAMLSchema is an experimental schema language for YAML data.
The goal is to make schemas look like the data they describe while keeping common validation constraints short and readable. It is intended to cover the same kind of data-model validation as JSON Schema, but with YAML-native syntax and a succinct form for human-authored schemas.
For the authoring syntax, see doc/dsl.md. For the broader language design, see doc/design.md. The built-in type reference covers scalar, null, arbitrary-value, and mapping types.
+email: +Str ~"\S+@\S+"
+port: +Int 1..65535
name: +Str
email?: +email
port: +port
tags: +Str[1+,!]
address:
street: +Str
city: +Str
zip: +Str ~"{digit}{5}(-{digit}{4})?"This schema describes a mapping where:
name,port,tags, andaddressare required.emailis optional because the key ends in?.tagsis a unique list with one or more string values.+emailand+portare reusable definitions.- Regexes, ranges, enums, list suffixes, and symbols express common constraints without verbose directive mappings.
- bin/ysd converts among succinct YAMLSchema, expanded YAMLSchema, and JSON Schema.
- test/ contains YAMLScript TAP tests for the converter.
- doc/design.md describes the language model, syntax, directives, JSON Schema mapping, and current implementation scope.
- doc/dsl.md is the normative succinct and explicit DSL reference.
- doc/json-schema.md describes roundtripping with JSON
Schema and the
.schema.jsonconvention. - note/yaml-schema-language-plan.md is the original design note.
YAMLSchema uses these file extensions:
.ysd.yamland.ysd.jsoncontain the human-maintained.ysdform..ysdc.yamland.ysdc.jsoncontain the canonical.ysdcform..schema.json,.schema.json.yaml,.schema.yaml, and.schema.ymlcontain JSON Schema.
The optional top-level .ysid identifies the human-maintained .ysd document.
Its suffix is .ysd.yaml in .ysd and both .ysdc serializations.
The corresponding JSON Schema $id uses .schema.json.
The converter replaces a recognized representation suffix and appends the
target suffix when none is present.
Typical flow:
contact.ysd.yaml -> contact.ysdc.yaml or contact.ysdc.json
contact.ysd.yaml -> contact.schema.json
The --to targets and explicit --from values are ysd, ysdc, and jsc.
The .ysd and .ysdc targets emit YAML by default, while jsc emits JSON.
Use -Y / --yaml or -J / --json to select a serialization explicitly.
The output options and a recognized output filename extension must agree.
Install the current release with Bash or Zsh:
source <(curl -sL yamlschema.org/install)For Fish:
curl -sL yamlschema.org/install | source -The installer puts ysd in $HOME/.local/bin for a normal user and in
/usr/local/bin for root.
Running the sourced command adds that directory to the current shell's PATH
and immediately enables tab completion and the YAMLSchema man pages.
The installer clones the matching release tag into
$PREFIX/share/yamlschema/ and prints the .rc line to add for future shells.
Set PREFIX or VERSION after the sourced installer command to override the
defaults:
source <(curl -sL yamlschema.org/install) \
PREFIX=/opt/yamlschema VERSION=0.1.3curl -sL yamlschema.org/install | \
source - PREFIX=/opt/yamlschema VERSION=0.1.3The installer requires Git, curl, GNU Make 3.81 or newer, and tar or
unzip for the platform archive.
Prebuilt releases are available for Linux Intel and ARM64, macOS ARM64,
Windows Intel and ARM64, and JavaScript WebAssembly.
The native archives contain ysd or ysd.exe and this ReadMe.
The js_wasm archive contains the raw ysd.wasm module for use with the Go
JavaScript WebAssembly runtime.
To clone, build, and install from source:
git clone https://github.com/yaml/yamlschema
cd yamlschema
make install PREFIX=$HOME/.localThis installs the built command under $PREFIX/bin and clones the current
committed HEAD into $PREFIX/share/yamlschema.
The target refuses to replace a checkout that has local changes.
It prints the .rc line to add to your shell configuration.
Run ysd --upgrade to fetch the installed checkout's configured default
branch and rebuild from its current HEAD.
For local development, source the repo .rc file to put bin/ on your
PATH, enable tab completion, and expose the man pages:
. ./.rcThe shell-specific completion files are share/complete.bash,
share/complete.zsh, and share/complete.fish.
After installation or local setup, try ysd --<TAB> or man ysd.
After that, the converter can be run as ysd:
ysd contact.schema.json
ysd contact.ysd.yaml
ysd -t ysd contact.schema.json
ysd -t ysdc -J contact.ysd.yaml
ysd -t ysdc contact.ysd.yaml
ysd -t jsc contact.ysd.yaml
ysd -t jsc -C contact.ysd.yaml
ysd -N contact.ysd.yaml
ysd -N legacy.schema.json
ysd -R contact.schema.json
ysd -R contact.ysd.yamlThe current converter script is ysd.
With no action option, it converts JSON Schema to .ysd and YAMLSchema to JSON
Schema on standard output.
Input defaults to stdin.
Use - explicitly to read JSON Schema or YAMLSchema from stdin.
Supply -f / --from when stdin does not make the input format unambiguous:
ysd -t ysd - < contact.schema.json
ysd -t jsc - < contact.ysd.yaml
ysd -f ysd -NC - < contact.ysd.yamlor from a file path:
ysd contact.schema.json
ysd contact.ysd.yaml
ysd -t ysd contact.schema.json
ysd -t jsc contact.ysd.yamlFor -R, an explicit -f takes precedence.
Without -f, input whose first non-whitespace character is { is treated as
JSON Schema; all other input is treated as .ysd.
For .ysd input, -R compares the expanded .ysdc from ysd -> ysdc with the
expanded .ysdc from ysd -> jsc -> ysdc.
The reported diff is therefore a .ysdc diff.
For JSON Schema input, -R continues to compare normalized JSON Schema.
CLI information:
ysd --help
ysd --versionExample input:
{
"properties": {
"name": {"type": "string"},
"email": {"type": "string", "pattern": "^\\S+@\\S+$"},
"tags": {
"type": "array",
"items": {"type": "string"},
"uniqueItems": true,
"minItems": 1
}
},
"required": ["name", "tags"]
}Expected .ysd.yaml output:
# Converted from JSON Schema
.open: true
name: +Str
email?: +Str ~"\S+@\S+"
tags: +Str[1+,!]The test suite is made of executable .t files under test/:
make testThe converter supports the direct mappings listed in
doc/json-schema.md, including oneOf, anyOf, allOf,
and not.
Unsupported JSON Schema keywords are retained as same-named dotted directives,
such as .if, and reported with a warning so conversion does not silently
discard them.