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.8.0.tar.gz (231.6 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.8.0-py3-none-win_arm64.whl (3.3 MB view details)

Uploaded Python 3Windows ARM64

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

Uploaded Python 3Windows x86-64

ryl-0.8.0-py3-none-musllinux_1_2_x86_64.whl (4.4 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

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

Uploaded Python 3musllinux: musl 1.2+ ARM64

ryl-0.8.0-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.8.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl (4.4 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ s390x

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

Uploaded Python 3manylinux: glibc 2.17+ ppc64le

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

Uploaded Python 3manylinux: glibc 2.17+ i686

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

Uploaded Python 3manylinux: glibc 2.17+ ARMv7l

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

Uploaded Python 3manylinux: glibc 2.17+ ARM64

ryl-0.8.0-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.8.0.tar.gz.

File metadata

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

File hashes

Hashes for ryl-0.8.0.tar.gz
Algorithm Hash digest
SHA256 261f4962c897bbb6cec475b37538ee3e0d22bddc311caea1cb1a3e48f0e58406
MD5 fbcf341df693ca4202529dc19c8c9b0f
BLAKE2b-256 e967226ea17d18d768d19d7a7c698c232da1a51b3f5803ba0b5f9cc866af2bc0

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.8.0.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.8.0-py3-none-win_arm64.whl.

File metadata

  • Download URL: ryl-0.8.0-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.8.0-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 178689d5998da26a6dff0b96e33225a0fe6ab9fcc0712081d9aeddc078bbf39d
MD5 18393fc447acd59b53a7def3ac3d7f99
BLAKE2b-256 04dc5d7d2d8825ed67a62154a9909c48218668793b5c5f507bfb26c070aeb65e

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.8.0-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.8.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: ryl-0.8.0-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.8.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 9f1ba0c7441c173cf8bea4442bcdaa7d14ab78eef04992209ed92225ef4c6aff
MD5 bccf463a99278a2fa4f34f51e7579226
BLAKE2b-256 2e42ca46edf609762ebc11de08667fb7b30655943b3f60c7baf498bdf4fc8829

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.8.0-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.8.0-py3-none-musllinux_1_2_x86_64.whl.

File metadata

  • Download URL: ryl-0.8.0-py3-none-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 4.4 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.8.0-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 7c1439aac51e241ed8f7c6a727c60863b49dd56090235d447f02985a9d28558b
MD5 82acb42200c5c52354617f8fc00d8829
BLAKE2b-256 e98e04faf348cfedd62ac8742bd10ce0e8fa457ca376fb5863265e21eee6666b

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.8.0-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.8.0-py3-none-musllinux_1_2_aarch64.whl.

File metadata

  • Download URL: ryl-0.8.0-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.8.0-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 28fd7355cc83019c7e835c3721dc3b5279db2a18532a7a745cd43fed06da4106
MD5 444d0fcf1154e60fbe3b17cd3349f3ff
BLAKE2b-256 9cc580c9b142eefbd3a01d42f45de950ad15015a6350f904b267ce70a75f0838

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.8.0-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.8.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for ryl-0.8.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ab237c0e20a4fc8caa3483b17780f06a0516ddf8bb44769b4111100e493e7da5
MD5 f9f0f155424d5abdb97c61887a8a10f8
BLAKE2b-256 c37115077605f21bcc60d67d38df462fea2016f321da43eb5f769752af0ee211

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.8.0-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.8.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for ryl-0.8.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 380f878b2f90e439e0e3e52f4ad3d98cadf26fe6de3416ddbf3070071580fc7e
MD5 249457491b9237f974f33b9ab93b93b2
BLAKE2b-256 e8d7ccb023514464235a43ba9aa7ffebbc6796503dacf75011cec7ace57f33c8

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.8.0-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.8.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for ryl-0.8.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 4792c185e4d8af4fe58686de19a1ca046a418714378c8901df7ac97421d05b8c
MD5 f231ee63777a8174f67532542b205987
BLAKE2b-256 cff63441757b37e07f874a387c9fe0fc34b44861d7fbb149a7b709f8d9cb5a40

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.8.0-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.8.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for ryl-0.8.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 35ac3445d8255abdcca7bbcb6e15f206f2d3bdecf1c29f57247dee4bb462b6b3
MD5 af36178a698dcc02c24e45a2a1fc1435
BLAKE2b-256 e3f7ed59007db4859ee6abdee746f1f7585f613b6cecceb71b3a296209fea6c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.8.0-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.8.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for ryl-0.8.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 757d62a45aece8e8094745e91f57e6b687cab2abd01505271a4f5bacb1e24101
MD5 16eca13eeae98eac715f488517a0d61a
BLAKE2b-256 aa4db5a6946ce4cff12d0bf5eba980fa3e42b0d5c8b3ef3268d16d109d9dfba5

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.8.0-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.8.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for ryl-0.8.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 295e47f75fa86a65f6844bfe677f8ac4e650a21c1f837f44fde7653a6318cf2b
MD5 2be9d241c3ea49f440225b868a35da6e
BLAKE2b-256 8a25876371b85883acdacc15c9de5908930b357651e8dc8c82fb12d6b25f02c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.8.0-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.8.0-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: ryl-0.8.0-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.8.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0d1b497f60269f69a27c7a2aa8a03219c5788aecbf7a0520d52ea71dc57ae39c
MD5 954a51b19d566e27a7dbed4fbb354f8d
BLAKE2b-256 8fa3a97acea32705a3b337788b5d784fad4b9a8f7d071b82e4753657cd9cf3fc

See more details on using hashes here.

Provenance

The following attestation bundles were made for ryl-0.8.0-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