Esc

comark-linter

Guides

Run lint-comark next to ESLint or oxlint, on staged files and in CI, or all of it as one Vite Doctor run.

ESLint and oxlint check your code, and lint-comark checks your Markdown. Neither reads :: blocks, so add lint-comark to the same scripts instead of to their configs:

pnpm add -D comark-linter
ESLint
{
  "scripts": {
    "lint": "eslint . && lint-comark \"content/**/*.md\""
  }
}
json
oxlint
{
  "scripts": {
    "lint": "oxlint && lint-comark \"content/**/*.md\""
  }
}
json

Quote the glob so the shell passes it as it is. lint-comark expands it and skips node_modules and dist. pnpm lint now fails on a broken document the way it fails on a lint error in code:

content/review.md:8:1 comark/unclosed-block `::compare` opened on line 8 is never closed. Add a line with `::` after its last child.
txt

If you use @eslint/markdown, keep it: it checks plain Markdown, and lint-comark checks what Comark adds on top.

With lint-staged, each tool gets the staged files it understands. lint-comark takes file paths as well as globs:

{
  "lint-staged": {
    "*.{js,ts,vue}": "eslint --fix",
    "*.{md,mdc}": "lint-comark"
  }
}
json

Swap eslint --fix for oxlint --fix if that's your linter.

pnpm lint exits with 1 on any problem, so a CI job needs only one step for both:

- run: pnpm install --frozen-lockfile
- run: pnpm lint
yaml

If your project is a Vite, Vue, Nuxt, or Nitro app, Vite Doctor can run lint-comark for you. It checks the framework mistakes your linter can't see, such as a raw fetch in a Nuxt setup or a secret in Vite's define. comark-linter/doctor adds every lint-comark rule to the same run:

pnpm add -D comark-linter vite-doctor
// doctor.config.ts
import comark from "comark-linter/doctor";
import { defineDoctorConfig } from "vite-doctor/config";

export default defineDoctorConfig({
  extends: ["auto", "comark/recommended"],
  extensions: [comark({ include: "content/**/*.md" })],
});
ts
{
  "scripts": {
    "lint": "eslint . && vite-doctor . --config doctor.config.ts --max-warnings 0"
  }
}
json

One report covers the code and the documents. Each lint-comark problem gets its own code, linked to its rule's page in Doctor.

Most lint-comark rules are warnings, and Vite Doctor exits with 0 on warnings alone, so --max-warnings 0 is what fails the script.

In a coding agent's terminal, Vite Doctor prints a compact report with the fix for each problem. --format sarif writes a file that GitHub code scanning uses to annotate a pull request. Vite Doctor lists the options.