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

Uploaded Python 3Windows ARM64

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

Uploaded Python 3Windows x86-64

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

Uploaded Python 3musllinux: musl 1.2+ x86-64

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

Uploaded Python 3musllinux: musl 1.2+ ARM64

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

Uploaded Python 3manylinux: glibc 2.17+ s390x

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

Uploaded Python 3manylinux: glibc 2.17+ ppc64le

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

Uploaded Python 3manylinux: glibc 2.17+ i686

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

Uploaded Python 3manylinux: glibc 2.17+ ARMv7l

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

Uploaded Python 3manylinux: glibc 2.17+ ARM64

ryl-0.9.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.9.0.tar.gz.

File metadata

  • Download URL: ryl-0.9.0.tar.gz
  • Upload date:
  • Size: 235.4 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.0.tar.gz
Algorithm Hash digest
SHA256 9b9d381fe317a589ce09aa89f371391ab6803e1a9be06817208c25955bbc84ab
MD5 b7c6216b4953b311715d6ba25d2ef28b
BLAKE2b-256 fab46549e8bf4ae75a8ca1aaa1ed1a8742476b395491051c6eda924bb381d754

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: ryl-0.9.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.9.0-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 e604bcc54f9edf751c9f75225d765bb0d9851ee35438c3ab193df4375e876b79
MD5 5cf96c5fa0d3966b5bc6ca0a9120e22e
BLAKE2b-256 8698d6ca1d35e702c123e9e97a607848de7bf76fdbda2f4f3be5b3dff511cfcc

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: ryl-0.9.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.9.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 cbd886f14f4562cc36d936e9d21bdfe40a504f8669825a3e4e01a94b4fab46c5
MD5 d9317d6ce5053ec690a2a20e6dfa693c
BLAKE2b-256 b639c535450c54779ea6be4d29780a3500cfdc6a8ff0d0c9d71388929fb61695

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: ryl-0.9.0-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.0-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 fcb2b3591c1fda70caceb5c8723546ecc101b2a4939c4da28448f5bd5bd3eb02
MD5 610ca00352f3cd3a3a3ba9bbf4719b8c
BLAKE2b-256 1a68c371506d64db47813fc56d096cbf25ff809c721a2dc8380d7430f8a684a8

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: ryl-0.9.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.9.0-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 a0266e5b5cbc63525d90f80c4cba0549c85d44b637d7fd940081bdb55132d0ab
MD5 391b1ffaf783dbdd8b72525db3989b33
BLAKE2b-256 8a723055df3e7f5a53cd88413b2fb1121c79fb099d03d57bece2d96737caf3ef

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for ryl-0.9.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 3938d8405aa910210312b4d7a750608dac4197125b81f29d65a248800ec507c5
MD5 a197e9c31b57a9ed250a5653381bfbe1
BLAKE2b-256 7d4c124b3b6793022c57e751bbe9802a4a3bb93dcff18455a31710afad0f77e5

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for ryl-0.9.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 8326261d7b13c4872524d746f456d97a9076e89f276ebabdc009003d04342711
MD5 043a177700731284356283b67c0e8cb2
BLAKE2b-256 723e483faa556fb675775af57efa38bfb1a7e8152fdf6ec582be963503cd3565

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for ryl-0.9.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 e7029487eac9b923178f3047e9a90b6eb138a022667506ea43be7ff6f4c0d21a
MD5 f88718bc3611818d34dfc90030c12d20
BLAKE2b-256 6902625649e27d6e20f444cf949f6fb3d7a255f60a456c6fa3117fb322e17685

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for ryl-0.9.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 d4104c53f9d2ac528103e6d4bd6c1aec98e57146101c7b30d454802a59edd7ac
MD5 2cf696141f4890b2df4f973e3784dcb1
BLAKE2b-256 8d9c47a6935bd7f7009920c6f51c6ff62f1e85f8da275d98d81781f6e92ddb8c

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for ryl-0.9.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 ba73b4f5cefd25b2954a450977aa5091f18ec849b6b8b0410ad2666ad9481777
MD5 abff83884cb85669d1a2696a32835a3a
BLAKE2b-256 23bd29839489962a07857f751927ba58b43a4ea9161e6751c5a3c89c3c4dcc66

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for ryl-0.9.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 75bc6845c4e5adee8aadd6d012530ab07b9f5aeada110a3f5f3ce81c8add3cd7
MD5 1a514ed19f40b5daab2d5a6dda633010
BLAKE2b-256 9a271aeb40e3e954147fbedc917a380f0442075d37bf758518bc55347fab99fd

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: ryl-0.9.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.9.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c63c3dfff331da6fc0dbf261060e7045479f56d73cfe3771687c4987a6812704
MD5 f9f313a01667ad6cb06de56e2aa3028d
BLAKE2b-256 b4b326d69ff1a0a8ba98a2c6fe1c39a83e2ff914352da9de9086675f135b271f

See more details on using hashes here.

Provenance

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