The official ESLint language plugin for Markdown that provides linting rules and code block extraction capabilities.
npx @tessl/cli install tessl/npm-eslint--markdown@7.2.0The official ESLint language plugin for Markdown files that provides comprehensive linting capabilities for Markdown content and code block extraction for separate code linting. It supports both CommonMark and GitHub Flavored Markdown formats with 19 specialized linting rules and a powerful processor for embedded code blocks.
npm install @eslint/markdown -Dimport markdown from "@eslint/markdown";For accessing specific components:
import markdown, { MarkdownSourceCode } from "@eslint/markdown";For CommonJS:
const markdown = require("@eslint/markdown");
const { MarkdownSourceCode } = markdown;// eslint.config.js
import { defineConfig } from "eslint/config";
import markdown from "@eslint/markdown";
export default defineConfig([
markdown.configs.recommended
// your other configs here
]);// eslint.config.js
import { defineConfig } from "eslint/config";
import markdown from "@eslint/markdown";
export default defineConfig([
...markdown.configs.processor
// your other configs here
]);// eslint.config.js
import { defineConfig } from "eslint/config";
import markdown from "@eslint/markdown";
export default defineConfig([
{
files: ["**/*.md"],
plugins: { markdown },
language: "markdown/gfm",
languageOptions: {
frontmatter: "yaml"
},
rules: {
"markdown/no-html": "error",
"markdown/require-alt-text": "error"
}
}
]);The @eslint/markdown plugin is built around several key components:
Core plugin setup and configuration management with pre-built configurations for common use cases.
interface Plugin {
meta: {
name: "@eslint/markdown";
version: "7.2.0";
};
processors: {
markdown: Processor;
};
languages: {
commonmark: MarkdownLanguage;
gfm: MarkdownLanguage;
};
rules: Rules;
configs: {
recommended: Config[];
processor: Config[];
"recommended-legacy": LegacyConfig;
};
}
// Additionally exported
interface MarkdownSourceCodeExport {
MarkdownSourceCode: typeof MarkdownSourceCode;
}Language implementations for parsing and processing Markdown files with support for CommonMark and GitHub Flavored Markdown formats.
class MarkdownLanguage {
constructor(options: { mode: "commonmark" | "gfm" });
parse(
text: string,
context: MarkdownLanguageContext
): OkParseResult<Root>;
}
interface MarkdownLanguageOptions {
frontmatter?: false | "yaml" | "toml" | "json";
}Processor for extracting fenced code blocks from Markdown files to enable individual linting of embedded code.
interface Processor {
meta: {
name: "@eslint/markdown/markdown";
version: "7.2.0";
};
preprocess(text: string, filename: string): Array<{
text: string;
filename: string;
}>;
postprocess(
messages: Message[][],
filename: string
): Message[];
supportsAutofix: boolean;
}19 specialized ESLint rules for common Markdown issues including heading structure, link validation, and content requirements.
interface Rules {
"fenced-code-language": Rule;
"heading-increment": Rule;
"no-bare-urls": Rule;
"no-duplicate-definitions": Rule;
"no-duplicate-headings": Rule;
"no-empty-definitions": Rule;
"no-empty-images": Rule;
"no-empty-links": Rule;
"no-html": Rule;
"no-invalid-label-refs": Rule;
"no-missing-atx-heading-space": Rule;
"no-missing-label-refs": Rule;
"no-missing-link-fragments": Rule;
"no-multiple-h1": Rule;
"no-reversed-media-syntax": Rule;
"no-space-in-emphasis": Rule;
"no-unused-definitions": Rule;
"require-alt-text": Rule;
"table-column-count": Rule;
}Advanced source code management with AST navigation, inline configuration parsing, and traversal utilities.
class MarkdownSourceCode {
constructor(options: { text: string; ast: Root });
/**
* The AST of the source code
*/
ast: Root;
/**
* Returns the parent of the given node
*/
getParent(node: Node): Node | undefined;
/**
* Returns all inline configuration nodes found in the source code
*/
getInlineConfigNodes(): Array<InlineConfigComment>;
/**
* Returns directive nodes that enable or disable rules
*/
getDisableDirectives(): {
problems: Array<FileProblem>;
directives: Array<Directive>;
};
/**
* Returns inline rule configurations
*/
applyInlineConfig(): {
problems: Array<FileProblem>;
configs: Array<{
config: { rules: RulesConfig };
loc: SourceLocation;
}>;
};
/**
* Traverse the source code and return the steps
*/
traverse(): Iterable<TraversalStep>;
}Helper functions for working with Markdown content and AST nodes.
/**
* Finds the line and column offsets for a given offset in a string
* @param text - The text to search
* @param offset - The offset to find
* @returns Location of the offset with line and column offsets
*/
function findOffsets(text: string, offset: number): {
lineOffset: number;
columnOffset: number;
};
/**
* Checks if a frontmatter block contains a title matching the given pattern
* @param value - The frontmatter content
* @param pattern - The pattern to match against
* @returns Whether a title was found
*/
function frontmatterHasTitle(value: string, pattern: RegExp | null): boolean;
/**
* Remove all HTML comments from a string
* @param value - The string to remove HTML comments from
* @returns The string with HTML comments removed
*/
function stripHtmlComments(value: string): string;interface MarkdownLanguageContext {
languageOptions: MarkdownLanguageOptions;
}
interface MarkdownRuleDefinition<Options = {}> {
// ESLint rule definition for Markdown-specific rules
}
interface MarkdownRuleVisitor {
// Visitor pattern for Markdown AST nodes
root?(node: Root): void;
heading?(node: Heading): void;
paragraph?(node: Paragraph): void;
// ... all mdast node types supported
}interface Block extends Code {
baseIndentText: string;
comments: string[];
rangeMap: RangeMap[];
}
interface RangeMap {
indent: number;
js: number;
md: number;
}
interface Toml extends Literal {
type: "toml";
data?: TomlData;
}
interface Json extends Literal {
type: "json";
data?: JsonData;
}
interface InlineConfigComment {
value: string;
position: SourceLocation;
}
interface FileProblem {
ruleId: string | null;
message: string;
loc: SourceLocation;
}
interface Directive {
type: DirectiveType;
node: InlineConfigComment;
value: string;
justification: string;
}
interface TraversalStep {
target: Node;
phase: 1 | 2;
args: [Node, Node?];
}^18.18.0 || ^20.9.0 || >=21.1.0v9.0.0 or greater