CLI tool
denoland/deno_lint avatar
denoland/deno_lint

deno_lint is the linter inside deno lint, packaged so anyone can embed it in Rust

Blazing fast linter for JavaScript and TypeScript written in Rust

1,584 stars191 forksRustMIT

At a glance

What is it?
deno_lint is a Rust crate for writing JavaScript and TypeScript linters, built on deno_ast and used by deno lint without being tied to it. Its pull request rules are unusually specific, and the crate's dependency list explains most of its shape.
Who is it for?
deno_lint suits a Rust project that wants Deno's lint rules without adopting Deno, since the crate states outright that it is not Deno specific and exposes no default features, so you can pull in only what you use.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 28 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • denoland/deno_lint1,584 ★ · +1
Star history
Repository2026-10-162026-10-23
denoland/deno_lint1.6k1.6k

1 Stars in the last 7 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

A linter engine, not a Deno plugin

The README opens with a description that sounds narrower than the project is: a Rust crate for writing JavaScript and TypeScript linters.

The second sentence is the one that matters. The crate powers `deno lint`, but it is not Deno specific and can be used as a standalone crate.

That sentence defines the boundary. Everything about the rule engine, the diagnostic model and the configuration shape is reusable, while everything about how Deno the runtime resolves configuration and formats output is not. For a Rust project with its own build and its own CI, that is the useful half.

The rule story is described in two lines. The crate ships with a set of built-in rules, including a `recommended` set that is enabled by default and requires no configuration. That last clause is a design decision worth noticing. A linter that requires a configuration file before it says anything is a linter a team has to opt into deliberately, and the recommended set is the mechanism by which this one is not.

What the crate does not do is enumerate the rules. The README points the list and its documentation to docs.deno.com/lint/rules/, so the catalogue lives outside this repository. That is a reasonable split given the rules are documented as user-facing documentation rather than API documentation, but it does mean you cannot answer the question what rules exist from the README alone.

The dependency list is the architecture

Cargo.toml is short enough to read as a design document, and it explains why deno_lint is the shape it is.

The package is `deno_lint` at version 0.84.1, edition 2021, MIT licensed, authored by the Deno authors, categorised as a development tool. It declares an empty default feature set, which means depending on the crate costs you nothing you did not ask for.

The load-bearing dependency is `deno_ast`, pinned at 0.53.2 and requested with the feature set `scopes`, `transforms`, `utils`, `visit`, `view` and `react`.

The rest are ordinary Rust infrastructure. `log` for diagnostics, `serde` with derive and `serde_json` for serialising results, `regex` for rules that need pattern matching inside text, `once_cell` for lazy statics, `derive_more` with the display feature for formatting, and `if_chain` for readable multi-condition matching. `phf` with macros is a perfect hash function map, which is how a fixed rule table gets built at compile time with no runtime lookup cost. `deno_semver` is there for version constraint handling.

So a rule is a visitor over `deno_ast` nodes, producing a serialisable diagnostic, looked up from a compile-time table.

Contributing a rule has a documentation requirement attached to it

The contributing section is the most detailed part of the README, and it is worth reading even if you only plan to use the crate, because it tells you what the maintainers consider a complete change.

Two conventions come first and neither is universal. If you are going to work on an issue, mention so in the issue comments before you start. And please be professional in the forums, where the project follows Rust's code of conduct.

Then there is the pull request checklist, and it has six items. There must be a related issue and it must be referenced in the pull request text. There must be tests covering the changes. `cargo test` must pass. Code must be formatted with `deno run --allow-run tools/format.ts`. `deno run --allow-run --allow-env tools/lint.ts` must pass.

Those two deno commands are the interesting detail. The project lints itself and formats itself using Deno running TypeScript tooling scripts, with `--allow-run` to let those scripts shell out, and `--allow-env` for the lint script. So a Rust codebase here is developed with Deno in the toolchain, which is coherent for a Deno project and mildly surprising if you expected Rust-only tooling.

The sixth item is the one that distinguishes this project: if you have added a new rule, open a separate pull request to denoland/docs with documentation for that rule. The rule and its documentation live in different repositories, and a change is not complete until both exist.

The top-level tree backs this up. There is a `tools/` directory holding the format and lint scripts, a `schemas/` directory, a `www/` directory, a `deno.json` at the root alongside `Cargo.toml`, and a `.rustfmt.toml` and `.clippy.toml` for the Rust side.

Building it from source, and what the release history says

The development section is four commands, and it starts with a toolchain requirement rather than a build target.

You need the latest stable version of Rust installed, and the README points at `rust-toolchain.toml` for the pin. That file is in the top level, so the required channel is in the repository rather than in prose.

The commands themselves:

shell
# check version
$ rustc --version

# build all targets
$ cargo build --all-targets

# test it
$ cargo test

The first line exists because the toolchain is pinned and it is worth confirming what you actually have before blaming the build.

Release history is where the versioning story becomes clear. Recent tags are 0.84.1 on 2026-05-02, 0.84.0 on 2026-04-02 and 0.83.0 on 2026-01-31. The version is below 1.0, and the recent releases shown are patch releases 0.84.0 and 0.84.1.

Note the gap between those dates and the repository state. The last push was on 2026-09-25, while the most recent release is from 2026-05-02. The project is not archived and its main branch has a later push than the most recent listed release. If you vendor from the repository, you may be tracking changes newer than that release.

Where a Rust-embedded linter is the wrong choice

Three situations call for a different answer.

First, if your lint needs type information. Nothing in the crate description, the feature list or the dependencies suggests types participate in analysis. `deno_ast` gives syntax and scopes; it is not a type checker. A rule that must know whether a value is `string | null` in the current scope is not something this framework is described as supporting, and you would need a separate type-aware pass. That also means the rules here are syntactic in character, which is a design choice rather than a limitation of the implementation.

Second, if you want autofix. The AST layer is requested with `transforms` among its features, so rewriting is possible at the layer below. But the README describes the crate as producing lint results and does not document a fix API, and lint rule sets that do not apply fixes safely are a design decision you should make deliberately rather than discover later.

Third, if you only need a handful of checks. Standing up a visitor framework, a rule table and a diagnostic serialisation path to catch three or four issues in a codebase is more infrastructure than the problem deserves, and it is infrastructure you then have to keep current as the AST crate moves. The `deno_ast` pin at 0.53.2 shows how tightly coupled this is: an upgrade of the AST crate is a coordinated change here, not something you absorb silently.

The case for using it anyway is narrow and specific: you want Deno's rule catalogue, with Deno's behaviour, inside a Rust toolchain that has nothing else to do with Deno. In that case the crate says exactly what you need, and it says it is usable standalone.

Editorial conclusion

deno_lint suits a Rust project that wants Deno's lint rules without adopting Deno, since the crate states outright that it is not Deno specific and exposes no default features, so you can pull in only what you use. It is the wrong choice if your rule set is small and stable, because wiring an AST visitor framework is more setup than writing a few regex checks, and it is the wrong choice if you need type-aware rules, since nothing in the crate description suggests type information participates in analysis. Before adopting, read the rule documentation on docs.deno.com rather than assuming parity with your current linter, and if you contribute a rule, remember the README requires a separate documentation pull request in denoland/docs as well as tests and a passing `cargo test`.

Frequently asked questions

Is deno_lint only usable inside Deno?

No. The README states it powers deno lint but is not Deno specific and can be used as a standalone crate. Cargo.toml also declares an empty default feature set.

Which AST library does deno_lint use?

It depends on deno_ast at version 0.53.2, with the features scopes, transforms, utils, visit, view and react.

How do I build and test deno_lint from source?

Install the latest stable Rust as pinned in rust-toolchain.toml, then run `cargo build --all-targets` and `cargo test`. Formatting uses `deno run --allow-run tools/format.ts` and linting uses `deno run --allow-run --allow-env tools/lint.ts`.

What must a pull request adding a lint rule include?

A related issue referenced in the PR text, tests covering the change, a passing cargo test, formatting and linting, plus a separate pull request to denoland/docs with the rule's documentation.

Where is the list of deno_lint rules documented?

The README does not enumerate the rules. The list and their documentation are hosted at docs.deno.com/lint/rules. Recent crate releases are 0.84.1 on 2026-05-02 and 0.84.0 on 2026-04-02.

Official sources

  1. denoland/deno_lint on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/denoland-deno-lint.svg)](https://hysenlabs.com/projects/denoland-deno-lint)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/denoland-deno-lint.svg)](https://hysenlabs.com/projects/denoland-deno-lint)

Was this useful?