unified-lint-rule
raw JSON → 3.0.1 verified Fri May 01 auth: no javascript
A helper package for the unified ecosystem that simplifies creating linting rules for processors like remark, retext, and rehype. Version 3.0.1 is the current stable release (ESM-only, requires Node.js 16+). It provides a `lintRule` function that takes metadata and a rule callback, handling plugin registration, error messages via VFile, and severity levels. Key differentiators: reduces boilerplate for unified lint rule authors, supports both sync and async rules, includes TypeScript types, and is part of the official remark-lint family.
Common errors
error ERR_REQUIRE_ESM ↓
cause Using CommonJS require() on an ESM-only package.
fix
Convert to ES module syntax: use
import { lintRule } from 'unified-lint-rule' and set "type": "module" in package.json. error TypeError: (intermediate value).message is not a function ↓
cause Calling `file.message()` incorrectly (e.g., passing options as first argument without string).
fix
Ensure the first argument to
file.message is a string describing the lint error: file.message('Incorrect extension: use ' + option + ''). error Error: Expected a `origin` string ↓
cause Passing invalid metadata to `lintRule` (e.g., missing colon in origin or non-string).
fix
Provide a properly formatted origin string like 'remark-lint:my-rule' (must contain a colon).
Warnings
breaking ESM-only: Node.js 16+ required. CommonJS require() will fail with ERR_REQUIRE_ESM. ↓
fix Switch to ES module syntax (import) and ensure package.json has "type": "module" or use .mjs extension.
gotcha The rule function's fourth parameter is the `Next` callback for async rules; omitting it makes the rule synchronous. If you need async, you must accept a fourth parameter and call it when done. ↓
fix Define rule with exactly 3 parameters for sync, or 4 parameters (including `Next`) for async, and always call next() to avoid hanging.
gotcha Options are passed as the third argument to the rule function. If the rule is configured with no options, the value is `undefined`. Default handling is manual. ↓
fix Check for undefined options and provide defaults explicitly (e.g., `const opts = options || 'md'`).
deprecated In unified-lint-rule v2, the `lintRule` function returned a plugin with a different signature. In v3, the return is a standard unified plugin. ↓
fix Ensure your unified version is compatible (>=10). No code changes needed if using unified's .use().
Install
npm install unified-lint-rule yarn add unified-lint-rule pnpm add unified-lint-rule Imports
- lintRule wrong
const { lintRule } = require('unified-lint-rule')correctimport { lintRule } from 'unified-lint-rule'
Quickstart
import { lintRule } from 'unified-lint-rule'
const remarkLintFileExtension = lintRule(
'remark-lint:file-extension',
function (tree, file, options) {
const ext = file.extname
const option = options || 'md'
if (ext && ext.slice(1) !== option) {
file.message('Incorrect extension: use `' + option + '`')
}
}
)
export default remarkLintFileExtension
// Usage with unified:
// import { unified } from 'unified'
// import remarkParse from 'remark-parse'
// import remarkStringify from 'remark-stringify'
// import remarkLintFileExtension from './my-lint-rule.js'
// const file = await unified().use(remarkParse).use(remarkLintFileExtension, 'md').process('')
// console.log(file.messages)