[KongchangAI]
· 1 min read· 866 words

declint: A Lightweight Tool for Writing Custom Lint Rules in YAML

declint: A Lightweight Tool for Writing Custom Lint Rules in YAML

declint lets teams define custom lint rules in YAML and Lua, covering both CI and editor workflows.

declint is a Rust-based lint tool designed to enforce team-specific coding conventions that mainstream linters miss. Rules are written declaratively in YAML using regex, with Lua available for complex logic. It integrates with CI via GitHub inline PR annotations and with editors via LSP for real-time feedback. Rules support embedded test cases, and the tool ships with presets for Python, Dockerfile, JSON, and more, plus community rulesets. It complements — rather than replaces — tools like ESLint or Pylint.

Linting tools are nearly universal in modern development workflows, yet mainstream linters tend to cover only general-purpose rules — leaving a team's unwritten coding conventions nearly impossible to enforce automatically. A new tool called declint aims to fill that gap by letting developers write custom lint rules directly in YAML, turning a team's internal standards into automatically enforceable checks.

declint project overview

Define Your Own Lint Rules in YAML

The core idea behind declint is straightforward: a rule is essentially a regex pattern plus a message. For a common example, if you want to catch teammates writing exception-swallowing code like except Exception: pass, all you need is a few lines of YAML:

version: 1
rules:
  - id: except-pass
    pattern: 'except Exception:\n *pass'
    severity: warning
    message: 'swallowed exception'

This declarative approach has an extremely low barrier to entry. Compared to the traditional linter workflow — writing a plugin, understanding the AST, publishing a package — declint reduces the cost of writing a custom rule to little more than knowing how to write a regex. That's exactly its value for team-specific conventions that stock linters will never ship built-in.

When Regex Isn't Enough, Use Lua

Regex covers a wide range of scenarios, but falls short when checks require contextual judgment or more complex logic. declint's answer is Lua scripting: when a rule can't be expressed as a regex, you can switch to Lua to write more sophisticated logic.

This layered design — YAML for simple cases, scripts for complex ones — is a pragmatic choice. It preserves the ease of declarative configuration while providing programming-language-level flexibility when needed, preventing the tool from hitting a capability ceiling too early.

Lua isn't an accidental choice here. As a lightweight embeddable scripting language, Lua's runtime footprint is tiny (typically just a few hundred KB), making it well-suited for embedding in a performance-conscious Rust binary while still providing full programming capabilities. Compared to JavaScript (as used in ESLint plugins) or Python, Lua's startup overhead is negligible and won't meaningfully slow down CI pipelines. For rule authors, Lua's clean syntax and gentle learning curve make it approachable, and it handles scenarios that regex struggles with — such as multi-line context analysis, counting, or stateful logic like "warn if there are more than three TODO comments in the same function" or "import statements must be in alphabetical order."

Full Coverage Across CI and Editor

The real measure of a linting tool is how seamlessly it fits into day-to-day development. declint covers both ends of the workflow:

  • CI integration: Rules can run in a continuous integration pipeline and output inline PR annotations via --format github, surfacing issues directly in the code review interface.
  • Editor integration: Via LSP (Language Server Protocol), declint can plug into editors. A Neovim plugin, declint.nvim, is already available for real-time feedback while coding.

This closed loop — from local editor to PR review — means rules aren't just a last-minute gate, but can surface issues early in development, reducing rework.

LSP (Language Server Protocol) is an open standard championed by Microsoft and introduced with VS Code in 2016, designed to decouple editor features (completions, go-to-definition, diagnostics) from language analysis logic. Through a unified protocol, a single language server can serve any LSP-compatible editor, eliminating the need to build separate plugins for each one. Because declint integrates via LSP, any LSP-compatible editor — VS Code, Helix, Emacs, Zed, and others — can in principle reuse the same rule logic; the Neovim plugin is just the starting point for ecosystem growth. For developers, the most immediate benefit of LSP integration is seeing squiggly underlines the moment a violation is typed, rather than discovering the issue at commit time or in CI.

Rules Are Testable and Shareable

declint also addresses rule maintainability. Each rule can carry embedded test fixtures and be verified directly with declint test. This means rules aren't opaque black boxes that get written and forgotten — they can be tested and trusted, just like production code.

For distribution, declint ships with built-in presets for a variety of languages and formats, including Python, INI, Markdown, shell, Dockerfile, TOML, JSON, and JS. It also supports community rulesets, letting developers pull in ready-made rule libraries with a single command rather than starting from scratch.

Installation and Positioning

declint is built in Rust and can be installed with cargo install declint. The author recently posted the project on Reddit to gather feedback, and it's still in the early stages of public exposure.

In terms of positioning, declint isn't trying to replace mature language-specific linters like ESLint or Pylint. Instead, it serves as a complement — specifically targeting the pain point of "team-specific conventions that general-purpose linters can't enforce." Its cross-language, cross-format support combined with low-friction YAML configuration makes it potentially very useful for polyglot repositories or teams that need a unified coding standard.

For teams that currently rely on code review comments for convention enforcement, or maintain a scattered collection of custom scripts for ad-hoc checks, declint offers a unified solution worth trying. As a new tool, however, the richness of its community rule ecosystem and its long-term maintenance trajectory will take time to prove out.

#declint#custom lint rules#YAML linter#Lua scripting#LSP integration#CI code review#team coding conventions
Share:

Related articles