Skip to main content

Fast YAML linter inspired by yamllint

Project description

ryl

ryl - the Rust Yaml Linter is intended to ultimately be a drop in replacement for yamllint. It is usable today, but parity and edge-case behavior are still maturing.

Compatibility note:

  • ryl aims to match yamllint behavior and includes many parity tests.
  • ryl uses the saphyr parser stack, while yamllint uses the PyYAML parser stack.
  • saphyr and PyYAML do not always agree on which files are valid YAML.

Quick Start

# Using uv (Python)
uvx ryl .

# Using npx (Node.js)
npx @owenlamont/ryl .

For prek / pre-commit integration, see ryl-pre-commit.

Installation

uv

uv tool install ryl

NPM

npm install -g @owenlamont/ryl

pip

pip install ryl

Cargo

cargo install ryl

Usage

ryl accepts one or more paths: files and/or directories.

Basic:

ryl <PATH_OR_FILE> [PATH_OR_FILE...]

Behavior:

  • Files: parsed as YAML even if the extension is not .yml/.yaml.
  • Directories: recursively lints .yml and .yaml files.
    • Respects .gitignore, global git ignores, and git excludes.
    • Does not follow symlinks.

Exit codes:

  • 0 when all parsed files are valid (or no files found).
  • 1 when any invalid YAML is found.
  • 2 for CLI usage errors (for example, no paths provided).

Examples:

# Single file
ryl myfile.yml

# Multiple inputs (mix files and directories)
ryl config/ another.yml

# Multiple directories
ryl dir1 dir2

# Explicit non-YAML extension (parsed as YAML)
ryl notes.txt

Help and version:

Fast YAML linter written in Rust

Usage: ryl [OPTIONS] [PATH_OR_FILE]...

Arguments:
  [PATH_OR_FILE]...  One or more paths: files and/or directories

Options:
  -c, --config-file <FILE>           Path to configuration file (YAML or TOML)
  -d, --config-data <YAML>           Inline configuration data (yaml)
  -f, --format <FORMAT>              Output format (auto, standard, colored, github,
                                     parsable) [default: auto]
                                     [possible values: auto, standard, colored,
                                     github, parsable]
      --print-toml-config-schema     Print the JSON Schema for ryl TOML config
                                     and exit
      --print-yaml-config-schema     Print the JSON Schema for yamllint-compatible
                                     YAML config and exit
      --fix                          Apply safe fixes in place before reporting
                                     remaining diagnostics
      --migrate-configs              Convert discovered legacy YAML config files
                                     into .ryl.toml files
      --list-files                   List files that would be linted (reserved)
  -s, --strict                       Strict mode (reserved)
      --no-warnings                  Suppress warnings (reserved)
      --migrate-root <DIR>           Root path to search for legacy YAML config
                                     files (default: .)
      --migrate-write                Write migrated .ryl.toml files (otherwise
                                     preview only)
      --migrate-stdout               Print generated TOML to stdout during migration
      --migrate-rename-old <SUFFIX>  Rename source YAML configs by appending
                                     this suffix after migration
      --migrate-delete-old           Delete source YAML configs after migration
  -h, --help                         Print help
  -V, --version                      Print version

Performance benchmarking

This repo includes a standalone benchmark script that compares PyPI ryl and yamllint using synthetic YAML corpora and hyperfine.

Prerequisites:

  • uv
  • hyperfine

Run a quick sample:

uv run scripts/benchmark_perf_vs_yamllint.py --file-counts 25,100 --file-sizes-kib 1,8 --runs 5 --warmup 1

Run a fuller matrix (explicit lists):

uv run scripts/benchmark_perf_vs_yamllint.py --file-counts 25,100,400,1000 --file-sizes-kib 1,8,32,128 --runs 10 --warmup 2

Run a fuller matrix (ranges with increments):

uv run scripts/benchmark_perf_vs_yamllint.py --file-count-start 100 --file-count-end 1000 --file-count-step 100 --file-size-start-kib 4 --file-size-end-kib 64 --file-size-step-kib 4 --runs 10 --warmup 2

The script uses Typer; use --help for all options.

Artifacts are written under manual_outputs/benchmarks/<UTC_TIMESTAMP>/:

  • benchmark.png and benchmark.svg: side-by-side facet plot with shared Y axis.
  • summary.csv: aggregated timing table.
  • meta.json: tool versions and run parameters.
  • hyperfine-json/: raw results from hyperfine.

Example benchmark figure (5x5 matrix, 5 runs per point):

Benchmark: ryl vs yamllint scaling (5x5 matrix, 5 runs per point)

Configuration

  • Flags:
    • -c, --config-file <FILE>: path to a YAML or TOML config file.
    • -d, --config-data <YAML>: inline YAML config (highest precedence).
    • --print-toml-config-schema: print the JSON Schema for .ryl.toml / ryl.toml / [tool.ryl].
    • --print-yaml-config-schema: print the JSON Schema for yamllint-compatible YAML config files such as .yamllint / .yamllint.yml / .yamllint.yaml.
    • --fix: apply safe fixes in place before reporting remaining diagnostics.
    • --list-files: print files that would be linted after applying ignores and exit.
    • --migrate-configs: discover legacy YAML configs and plan TOML migration.
    • --migrate-root <DIR>: root to search for legacy YAML configs (default .).
    • --migrate-write: write migrated .ryl.toml files (without this it is preview-only).
    • --migrate-stdout: print generated TOML in migration mode.
    • --migrate-rename-old <SUFFIX>: rename discovered legacy YAML config files after writing.
    • --migrate-delete-old: delete discovered legacy YAML config files after writing.
    • -f, --format, -s, --strict, --no-warnings: reserved for compatibility.
  • Discovery precedence: inline --config-data > --config-file > env YAMLLINT_CONFIG_FILE (global) > nearest project config up the tree: TOML (.ryl.toml, ryl.toml, pyproject.toml with [tool.ryl]) then YAML fallback (.yamllint, .yamllint.yml, .yamllint.yaml)

    user-global ($XDG_CONFIG_HOME/yamllint/config or ~/.config/yamllint/config) > built-in defaults.

  • Rules Documentation: see docs/rules.md for a full list of supported rules and their fixable status.
  • TOML and YAML are not merged during discovery. If a TOML project config is found, YAML project config discovery is skipped (and ryl prints a warning).
  • Native fix policy and per-file ignores are TOML-only. YAML config remains yamllint-compatible and does not support ryl-native settings.
  • Per-file behavior: unless a global config is set via --config-data, --config-file, or YAMLLINT_CONFIG_FILE, each file discovers its nearest project config. Ignores apply to directory scans and explicit files (parity).
  • Presets and extends: supports yamllint’s built-in default, relaxed, and empty via extends. Rule maps are deep-merged; scalars/sequences overwrite.
  • TOML preset examples: see docs/config-presets.md for default/relaxed equivalents.
  • Canonical schema artifacts are checked into this repo as:
    • ryl.toml.schema.json for .ryl.toml / ryl.toml / [tool.ryl]
    • ryl.yaml.schema.json for yamllint-compatible YAML config files such as .yamllint / .yamllint.yml / .yamllint.yaml
  • SchemaStore sync only targets the native TOML config and publishes a draft-07 projection for ryl.toml / .ryl.toml. SchemaStore cannot target the [tool.ryl] table inside pyproject.toml, so that remains covered by the broader pyproject.toml schema association.
  • Release-time SchemaStore sync updates owenlamont/schemastore:ryl-schema-update after a release succeeds and prints the manual upstream PR details in the workflow summary.
  • Regenerate them with:
    • cargo run --quiet --bin ryl -- --print-toml-config-schema > ryl.toml.schema.json
    • cargo run --quiet --bin ryl -- --print-yaml-config-schema > ryl.yaml.schema.json
  • Print the SchemaStore projection locally with:
    • uv run scripts/print_ryl_schemastore_schema.py > /tmp/ryl.schemastore.json

Example TOML config (.ryl.toml):

yaml-files = ["*.yaml", "*.yml"]
ignore = ["vendor/**", "generated/**"]
locale = "en_US.UTF-8"

[per-file-ignores]
"**/values.yaml" = ["document-start"]
"**/kustomization.yaml" = ["document-start"]
# `!` negates the pattern, so this ignores truthy outside Kubernetes manifests.
"!k8s/**.yaml" = ["truthy"]

[rules]
document-start = "disable"

[rules.line-length]
max = 120

[rules.truthy]
allowed-values = ["true", "false"]

[fix]
fixable = ["ALL"]
unfixable = []

For a fully expanded TOML example that names every built-in rule explicitly, see /.ryl.toml.example.

Migration example:

# Preview migration actions
ryl --migrate-configs --migrate-root .

# Write .ryl.toml files and keep old files with a suffix
ryl --migrate-configs --migrate-root . --migrate-write --migrate-rename-old .bak

Acknowledgements

This project exists thanks to the tooling and ecosystems around YAML linting and developer automation, especially:

  • yamllint - for giving me the shoulders to stand on and the source of many of the automated tests that ryl uses now to check for behaviour parity. Copying the behaviour of an existing tool is infinitely easier than building one from scratch - there'd be no ryl without yamllint.
  • ruff - for showing the power of Rust tooling for Python development and inspiring the config and API for ryl.
  • rumdl - for giving me another template to follow for Rust tooling and showing me almost the only dev tool I was still using after this that wasn't written in Rust was yamllint (which inspired me to tackle this project)
  • saphyr - ryl is built on saphyr and saphyr's developers were very patient in showing some of the nuance and complexity of parsing YAML which I was embarrassingly ignorant of when start ryl.
  • esbuild and biome - for providing the "binary wrapper" blueprint for distributing high-performance native tools via NPM.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ryl-0.9.1.tar.gz (236.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

ryl-0.9.1-py3-none-win_arm64.whl (3.3 MB view details)

Uploaded Python 3Windows ARM64

ryl-0.9.1-py3-none-win_amd64.whl (3.6 MB view details)

Uploaded Python 3Windows x86-64

ryl-0.9.1-py3-none-musllinux_1_2_x86_64.whl (4.5 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

ryl-0.9.1-py3-none-musllinux_1_2_aarch64.whl (4.2 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

ryl-0.9.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.3 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

ryl-0.9.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl (4.4 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ s390x

ryl-0.9.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (4.9 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ppc64le

ryl-0.9.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl (4.5 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ i686

ryl-0.9.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (4.1 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARMv7l

ryl-0.9.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.2 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

ryl-0.9.1-py3-none-macosx_11_0_arm64.whl (3.9 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

File details

Details for the file ryl-0.9.1.tar.gz.

File metadata

  • Download URL: ryl-0.9.1.tar.gz
  • Upload date:
  • Size: 236.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for ryl-0.9.1.tar.gz
Algorithm Hash digest
SHA256 3f58651ec3d6145de7e0708fe75a4742ccb12175b54b47d4ed07f3be354a0f39
MD5 62781e37a6d1d0bb899b2b03d0ea4a8e
BLAKE2b-256 0fd8ac10dc7a12ff14b34d8966e488cfef73d1f7296d5e9b822909dfb06c8352

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.9.1.tar.gz:

Publisher: release.yml on owenlamont/ryl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ryl-0.9.1-py3-none-win_arm64.whl.

File metadata

  • Download URL: ryl-0.9.1-py3-none-win_arm64.whl
  • Upload date:
  • Size: 3.3 MB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for ryl-0.9.1-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 93f238e0b4b26ce3d229a7da149c0ca800ecdbc28af7713924e9a74d27ed8267
MD5 2927e3fff931d508593260ef8937080f
BLAKE2b-256 4bec4104a5cd5854416f31d5ac10acaad8d4d919eada607def2c8cba06cafe25

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.9.1-py3-none-win_arm64.whl:

Publisher: release.yml on owenlamont/ryl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ryl-0.9.1-py3-none-win_amd64.whl.

File metadata

  • Download URL: ryl-0.9.1-py3-none-win_amd64.whl
  • Upload date:
  • Size: 3.6 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for ryl-0.9.1-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 5e747b0e5ee0dac5c412c86463da7743f5c4ccc9af5c33ce1c6175907e41a13b
MD5 692928af4874ba64ce990db9dd3298c4
BLAKE2b-256 6d1b0b16e6b2920a577c5ec94e86d7f76fb26dc788d87bf88e250ecb3bcb4ae6

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.9.1-py3-none-win_amd64.whl:

Publisher: release.yml on owenlamont/ryl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ryl-0.9.1-py3-none-musllinux_1_2_x86_64.whl.

File metadata

  • Download URL: ryl-0.9.1-py3-none-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 4.5 MB
  • Tags: Python 3, musllinux: musl 1.2+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for ryl-0.9.1-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 a508bb08256fea979dd6a978e2382d3945dab06c883c882f5f086333c59971fa
MD5 f39781634bc948c7ee7c9a021e60f544
BLAKE2b-256 05fb9843b93a87869b6819c1d9b1911cd00b3b654181da94c21492ceda4a6fa8

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.9.1-py3-none-musllinux_1_2_x86_64.whl:

Publisher: release.yml on owenlamont/ryl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ryl-0.9.1-py3-none-musllinux_1_2_aarch64.whl.

File metadata

  • Download URL: ryl-0.9.1-py3-none-musllinux_1_2_aarch64.whl
  • Upload date:
  • Size: 4.2 MB
  • Tags: Python 3, musllinux: musl 1.2+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for ryl-0.9.1-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 4850e2b1ccb598235bf918d66001896318d1f213e9f41937bfb5fda99272ce7c
MD5 13bc5ac99535997ef054f33bd50f8719
BLAKE2b-256 25e32c75a18d77725600f39572cc47b86d348e720204f2af40b0e52cc9f42806

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.9.1-py3-none-musllinux_1_2_aarch64.whl:

Publisher: release.yml on owenlamont/ryl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ryl-0.9.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for ryl-0.9.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 8ce7eb6ce1037614a1b86a8ed9b5f8a69904a5f38801ed43c5e54f98983da2a5
MD5 0acad5457ac43947a31ba88052083c56
BLAKE2b-256 52646b5b8c78e1a2c9ce3516a4c5c1d701621810c33af3b8b1fa6a35b2092ab6

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.9.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on owenlamont/ryl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ryl-0.9.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for ryl-0.9.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 1fdd035171b9b6014b3245d7ae60f180c6c3f96356249ae4bdd134e71eea9496
MD5 86053b98a9bb5ff1bcf51c5cf1369147
BLAKE2b-256 e6470fef908322863e2e4195f8076e907c0a15c7c242794ad8c941f76ab12320

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.9.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl:

Publisher: release.yml on owenlamont/ryl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ryl-0.9.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for ryl-0.9.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 ea8441e29bfaf4ae4faaeae393634c1f3d8c725dbb576f8da44ca41725c11975
MD5 f68e28ba69cbe18a9909b12db9177664
BLAKE2b-256 35e9d059f4d6f8a4a5063fdc4272a8a846859d2388ad7cabfcf3cbd7bf9c094d

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.9.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl:

Publisher: release.yml on owenlamont/ryl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ryl-0.9.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for ryl-0.9.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 59d2a3ebfaeed51145e4e682125733e4275276e54564b5ddfd49b6fe57ab33ad
MD5 fff30fbac3b2fa3ce9d3bcf8208a97e5
BLAKE2b-256 5639241bc9dd055fd9949a4ec9f34e6c6f066520e4fd3c761b39b8bc77c19d9f

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.9.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl:

Publisher: release.yml on owenlamont/ryl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ryl-0.9.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for ryl-0.9.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 b31478bf8170d4a6ec9528fb0fca506b5c0b816a61a7f30225fe90a52ccf39fb
MD5 d35ca6f8ace9c03cf3535055a8e85ac2
BLAKE2b-256 56111f8a5f85f88f6e959f3b023efd7c59ac223f62e351ede4a40315a78b34f4

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.9.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl:

Publisher: release.yml on owenlamont/ryl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ryl-0.9.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for ryl-0.9.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 ffa9ca102ef396534c8ea13ed2cda1518812b8ede0d419e2a668a7425e4878b9
MD5 fb57c5a203333283ca14bf96cbf5e741
BLAKE2b-256 e8f4b9dc525e9845973b50f2ab00e798879ff4910ff3dbd8e3125f6466b41a75

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.9.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on owenlamont/ryl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ryl-0.9.1-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: ryl-0.9.1-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 3.9 MB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for ryl-0.9.1-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 770b715e06f2f8fe79b58f81ddbc2b65fd82c7c2753bc05b5919979578dfa152
MD5 563fd6bad970cb4eda9982617aa4a0be
BLAKE2b-256 ddff121d3fe60faf32483a74fdcd78df3fa0c697e12b90cb7599a331484038c9

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.9.1-py3-none-macosx_11_0_arm64.whl:

Publisher: release.yml on owenlamont/ryl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page