Lintel validates JSON, YAML, TOML, JSON5, and JSONC files against JSON Schema in a single command. It auto-discovers schemas via SchemaStore, the Lintel catalog, inline $schema properties, and YAML modelines — zero config required.
Fast. Written in Rust with no async runtime, deterministic schema caching, and pre-compiled SchemaStore catalog matching. Warm runs are pure computation.
Drop-in CI check. Machine-parseable output, nonzero exit codes on failure, .gitignore-aware file walking. Add one line to your pipeline and catch config mistakes before they ship.
Zero config. Point it at your repo and go. Lintel figures out which schemas to use.
cargo install lintelOr with npm:
npx @lintel/lintel check
bunx @lintel/lintel check
pnpx @lintel/lintel checkOr with Nix:
nix run github:lintel-rs/lintel# validate with rich terminal output
lintel check
# validate with CI-friendly one-error-per-line output
lintel ci
# generate a lintel.toml with auto-detected schemas
lintel init
# convert between formats
lintel convert config.yaml --to tomlLintel auto-discovers schemas in priority order:
- YAML modeline —
# yaml-language-server: $schema=... - Inline
$schemaproperty — in the document itself lintel.tomlmappings — custom[schemas]table entries- Custom registries — additional catalogs from
lintel.toml - Lintel catalog — aggregates SchemaStore with additional schemas (Cargo.toml, Claude Code, devenv.yaml, and more)
Files without a matching schema are silently skipped. Lintel respects .gitignore — node_modules, target/, and build artifacts are skipped automatically.
The Lintel catalog is an aggregate of SchemaStore and additional schemas for tools that don't have SchemaStore entries. When both catalogs have a match, the Lintel catalog takes precedence.
See the lintel-rs/catalog repository for more information.
Currently includes additional schemas for:
- Cargo.toml — Rust package manifests
- Claude Code — agent, skill, and command definitions
- devenv.yaml — devenv configuration
To add your own catalogs, use registries in lintel.toml:
registries = ["github:my-org/my-schemas"]The github:org/repo shorthand resolves to https://raw.githubusercontent.com/org/repo/master/catalog.json.
Lintel supports project configuration via lintel.toml:
# stop walking up the directory tree
root = true
# exclude files from validation
exclude = ["vendor/**", "testdata/**"]
# map file patterns to schema URLs
[schemas]
"my-config.yaml" = "https://example.com/my-schema.json"
".ci/*.yml" = "//schemas/ci.json" # // resolves relative to lintel.toml
# additional schema catalogs
registries = ["github:my-org/my-schemas"]
# rewrite schema URLs (e.g. for local development)
[rewrite]
"http://localhost:8000/" = "//schemas/"
# per-file overrides
[[override]]
files = ["schemas/vector.json"]
validate_formats = falseAdd Lintel as an input in devenv.yaml:
inputs:
lintel:
url: github:lintel-rs/lintel
flake: trueThen use it in devenv.nix:
{ pkgs, inputs, ... }:
let
lintel = inputs.lintel.packages.${pkgs.system}.default;
in
{
packages = [ lintel ];
# optional: run lintel as a pre-commit hook
git-hooks.hooks.lintel = {
enable = true;
name = "lintel";
entry = "${lintel}/bin/lintel check";
types_or = [ "json" "yaml" ];
};
}Use the official lintel-rs/action:
- uses: lintel-rs/action@v1Copyright Ian Macalinao. Licensed under the Apache License, Version 2.0.