ban-unused-ignore only works with file-level directives
To ignore the 'ban-unused-ignore' rule itself, use file-level ignore directives like '// deno-lint-ignore-file ban-unused-ignore'. Line-level directives like '// deno-lint-ignore ban-unused-ignore' do not work for suppressing ban-unused-ignore.
deno lint basic command
The command 'deno lint' lints all TypeScript and JavaScript files in the current directory.
deno lint specific files or directories
Use 'deno lint src/ main.ts' to lint specific files or directories.
deno lint --watch flag
The --watch flag automatically re-lints files when they change.
deno lint exit code on violations
The deno lint command exits with a non-zero status code when it finds violations, making it suitable for CI pipelines.
deno lint --rules flag
The --rules flag displays all available rules. Run 'deno lint --rules' to view over 100 available linting rules.
deno lint --ignore flag
The --ignore flag excludes files from linting. Usage: 'deno lint --ignore=dist/,build/'
deno lint available rule tags
The available tags for rule sets are: 'recommended' and 'fresh'. Rules not belonging to any tag must be explicitly listed in the 'include' field to be enabled.
deno-lint-ignore-file directive
Use '// deno-lint-ignore-file' at the top of a file to ignore all lint violations in that file. The directive must be placed before the first statement or declaration.
deno-lint-ignore-file with specific rules
Use '// deno-lint-ignore-file rule1 rule2' to ignore specific rules in an entire file. List multiple rule names separated by spaces.
deno-lint-ignore-file with reason
Add a reason for ignoring a file using '// deno-lint-ignore-file -- reason for ignoring'.
deno-lint-ignore line level directive
Use '// deno-lint-ignore rule1 rule2' on the line immediately preceding the offending code to ignore specific rules for that line. Multiple rule names are separated by spaces.
deno-lint-ignore with reason
Add a reason for ignoring a line using '// deno-lint-ignore rule-name -- reason for ignoring'.
Multiple deno-lint-ignore-file directives
If multiple '// deno-lint-ignore-file' directives exist in a file, only the first one is effective. All subsequent ignore directives of this type are ignored.
ban-unused-ignore rule
The 'ban-unused-ignore' rule detects lint ignore directives that don't suppress any diagnostics, useful for discovering unnecessary ignore directives after code refactoring.
deno lint with custom configuration in CI
The `deno lint` command scans code for syntax errors and style issues. To use a custom linter configuration, add a configuration file with the `--config <myconfig>` flag.
Lint rule context.report API
Within an AST visitor method, call context.report() with an object containing: node (the AST node), message (string describing the issue), and optionally fix (a function receiving a fixer instance). The fix function can return a single fix, an array of fixes, or yield multiple fixes as a generator.
Lint plugin API availability
The lint plugin API is available in Deno 2.2.0 and later with no unstable flag required. The API is still evolving and may change in a future release.
Lint plugins loading via deno.json
Plugins are loaded via the lint.plugins setting in deno.json. The value is an array of plugin specifiers which can be paths, npm: or jsr: specifiers.
Lint plugin structure and default export
A lint plugin always has a default export which is the plugin object. The plugin object has a name property (string shown in error output) and a rules property (object where property names are rule names shown in error output).
Lint rule create method
Each rule has a create(context) method that is called when a file is being linted. It must return an AST visitor object with visitor methods or selectors as property names.
Lint plugin selector syntax
Lint plugin selectors support the following syntax: Foo + Foo (next sibling), Foo > Bar (child combinator), Foo ~ Bar (subsequent sibling combinator), Foo Bar (descendant combinator), Foo[attr] (attribute existence), Foo[attr.length < 2] (attribute value comparison), Foo[attr=/(foo|bar)*/] (attribute value regex), :first-child, :last-child, :nth-child(2n + 1), :not(> Bar), :is(> Bar), :where(> Bar) (same as :is()), :matches(> Bar) (same as :is()), :has(> Bar), IfStatement.test (field selector), and :exit (pseudo-class valid only at end of selector, calls function while traversing up the tree instead of down).
Lint plugin fixer methods
The fixer object passed to fix() has these methods: insertTextAfter(node, text), insertTextAfterRange(range, text), insertTextBefore(node, text), insertTextBeforeRange(range, text), remove(node), removeRange(range), replaceText(node, text), and replaceTextRange(range, text).
Getting source code in lint rule fix
To get the source code of any node in a lint rule, use context.sourceCode.getText(node) to obtain the original source text.
Lint rule destroy hook
A lint rule can have an optional destroy() hook that runs after a file has been linted and just before the plugin context is destroyed. This is used for cleanup code.
Lint rule plugin global state warning
It is not safe to assume that plugin code will be executed again for each linted file. Do not keep global state, and prefer to do cleanup in the destroy hook, as deno lint may decide to reuse the existing plugin instance.
Excluding custom lint rules
Custom rules provided by a plugin can be disabled by adding them to the lint.rules.exclude key in deno.json. The format of a custom lint rule is always <plugin-name>/<rule-name>.
Ignoring custom lint reports with code comments
To disable a reported lint error for a particular location in code, place a code comment before it with the syntax: // deno-lint-ignore <my-plugin>/<my-rule>. This disables the lint rule from a lint plugin for that particular line.
Testing lint plugins with Deno.lint.runPlugin
The Deno.lint.runPlugin API provides a way to test plugins. It takes the plugin object, a dummy filename, and source code as a string, and returns diagnostics array. Each diagnostic has properties id (format: <plugin-name>/<rule-name>), message, and optionally fix (array of objects with range and text properties).
Deno.lint.runPlugin API availability restriction
The Deno.lint.runPlugin API is only available in the deno test and deno bench subcommands. Trying to use it with any other subcommand will throw an error.
Example lint plugin
This example plugin forbids identifiers named '_a' and suggests replacing them with '_b'. The plugin has name 'my-plugin' with a rule 'my-rule' that uses an Identifier visitor to check node names and provides a fix using fixer.replaceText():
const plugin: Deno.lint.Plugin = {
name: "my-plugin",
rules: {
"my-rule": {
create(context) {
return {
Identifier(node) {
if (node.name === "_a") {
context.report({
node,
message: "should be _b",
fix(fixer) {
return fixer.replaceText(node, "_b");
},
});
}
},
};
},
},
},
};
export default plugin;
Example lint plugin with selector
This example uses a selector to match CallExpression nodes where the callee name is 'require', detecting require() calls:
const plugin: Deno.lint.Plugin = {
name: "my-plugin",
rules: {
"my-rule": {
create(context) {
return {
'CallExpression[callee.name="require"]'(node) {
context.report({
node,
message: "Don't use require() calls to load modules",
});
},
};
},
},
},
};
export default plugin;
Example lint plugin test
This example tests the my-plugin defined above using Deno.lint.runPlugin:
import { assertEquals } from "jsr:@std/assert";
import myPlugin from "./my-plugin.ts";
Deno.test("my-plugin", () => {
const diagnostics = Deno.lint.runPlugin(
myPlugin,
"main.ts", // Dummy filename, file doesn't need to exist.
"const _a = 'a';",
);
assertEquals(diagnostics.length, 1);
const d = diagnostics[0];
assertEquals(d.id, "my-plugin/my-rule");
assertEquals(d.message, "should be _b");
assertEquals(d.fix, [{ range: [6, 8], text: "_b" }]);
});
deno.json lint.plugins configuration example
To load a lint plugin, add it to the lint.plugins array in deno.json:
{
"lint": {
"plugins": ["./my-plugin.ts"]
}
}
deno.json exclude custom lint rules example
To exclude a custom lint rule from a plugin, add it to lint.rules.exclude in deno.json:
{
"lint": {
"plugins": ["./my-plugin.ts"],
"rules": {
"exclude": ["my-plugin/my-rule"]
}
}
}