Repository structure linter

alint enforces the shape of your repository: which files must exist, what they're named, what's inside them at the structural level, and how they relate to one another. Most linters check the code inside files; alint checks the files themselves.

What "structure" means in practice

Four rule families cover the bulk of structural validation. The full catalogue lists 60 kinds; these are the load-bearing ones.

Family Rule kinds What it answers
Existence file_exists, dir_exists Required files and directories are present: LICENSE, README.md, CODEOWNERS, language manifests, per-package scaffolding.
Naming filename_case, filename_regex Filenames follow conventions: PascalCase React components, kebab-case docs, snake_case Rust modules, test files alongside their subject.
Text hygiene final_newline, trailing_whitespace, line_endings Format invariants hold across the tree: POSIX final newlines, no stray trailing whitespace, consistent line endings, no Unicode bidi control characters.
Structured query json_path_*, yaml_path_*, toml_path_* Values inside config files are correct: every package.json has a license; every Cargo.toml sets edition = "2021"; every GitHub workflow pins actions/checkout@v4.

Cross-file relations (pair, for_each_dir, unique_by, every_matching_has) layer on top: every *.proto has a generated counterpart, every TS path-alias resolves, no two package.jsons share a name.

How it's expressed

One .alint.yml, declarative, with a JSON Schema for editor autocomplete. extends: pulls in bundled per-ecosystem rulesets; the rules: block adds repo-specific checks.

extends:
  - alint://bundled/rust@v1
  - alint://bundled/oss-baseline@v1

rules:
  - kind: filename_case
    paths: ["src/**/*.rs"]
    case: snake

  - kind: file_exists
    path: "CODEOWNERS"

Performance

alint is a single static Rust binary with no runtime dependencies. Recent benchmarks:

Per-release benchmark history lives in docs/benchmarks/HISTORY.md.

See alint applied to real codebases in the case-study gallery, or read the vs other repo-level linters comparison.