Compact mdast Trees
mdast-util-compact is a specialized utility within the unified (syntax-tree) ecosystem designed to normalize mdast (Markdown Abstract Syntax Tree) trees by merging adjacent text nodes and collapsing blockquotes. Its primary use case is to clean up an mdast tree after programmatically modifying it, making the tree structure more consistent with how it would be generated by a parser. The current stable version is 5.0.0. The package follows semantic versioning with major releases introducing breaking changes, often related to Node.js version support or ESM migration, as well as updates to underlying `mdast` type definitions. A key differentiator is its explicit recommendation against frequent use, suggesting developers should ideally maintain clean trees themselves rather than relying on this utility post-hoc. It is an ESM-only package and fully typed with TypeScript.
Common errors
-
Error [ERR_REQUIRE_ESM]: require() of ES Module ...mdast-util-compact/index.js from ... not supported.
cause Attempting to import `mdast-util-compact` using CommonJS `require()` syntax in a project where the package is ESM-only.fixChange `const { compact } = require('mdast-util-compact')` to `import { compact } from 'mdast-util-compact'`. Ensure your project's `package.json` includes `"type": "module"` or your file uses the `.mjs` extension. -
TypeError: compact is not a function
cause Attempting to use `import compact from 'mdast-util-compact'` (default import) when `mdast-util-compact` only provides named exports, or an incorrect `require()` pattern.fixUse the correct named import: `import { compact } from 'mdast-util-compact'`. -
SyntaxError: Cannot use import statement outside a module
cause Using `import` syntax in a file that Node.js interprets as a CommonJS module (e.g., a `.js` file without `"type": "module"` in `package.json`, or a `.cjs` file).fixRename your file to `.mjs` or add `"type": "module"` to your `package.json`. If you must use CommonJS, you will need to stick to `mdast-util-compact@^3` or earlier, as v4+ is ESM-only. -
Error: mdast-util-compact requires Node.js 16 or later.
cause Running `mdast-util-compact@5.0.0` on an unsupported Node.js version (e.g., Node.js 14).fixUpgrade your Node.js runtime to version 16 or newer. If upgrading is not an option, downgrade to `mdast-util-compact@^4` which supports older Node.js versions.
Warnings
- breaking mdast-util-compact is an ESM-only package since v4.0.0, strictly enforced through 'export' maps in v5.0.0. Attempting to use CommonJS 'require()' will result in an error.
- breaking Version 5.0.0 requires Node.js 16 or higher due to updates in underlying dependencies and ecosystem standards.
- breaking The `compact(tree)` function now explicitly returns `undefined` in v5.0.0. It modifies the provided tree in-place. Previous major versions might have returned the modified tree itself.
- breaking Version 3.0.0 introduced significant changes to align tree interpretation with CommonMark and the broader 'remark' ecosystem, potentially altering how specific Markdown structures are represented in the mdast tree.
- gotcha The maintainers explicitly advise against frequent or primary reliance on `mdast-util-compact`, suggesting that mdast trees should ideally be kept clean during direct manipulation rather than consistently requiring a post-processing step.
- gotcha Updating to v5.0.0 includes an update to `@types/mdast`. This might introduce type conflicts or require updating other packages that depend on specific versions of `@types/mdast`.
Install
-
npm install mdast-util-compact -
yarn add mdast-util-compact -
pnpm add mdast-util-compact
Imports
- compact
import compact from 'mdast-util-compact'
import { compact } from 'mdast-util-compact' - compact (browser/Deno)
import { compact } from 'https://esm.sh/mdast-util-compact@5'
Quickstart
import { u } from 'unist-builder';
import { compact } from 'mdast-util-compact';
// Create a sample mdast tree with adjacent text nodes and blockquotes
const tree = u('root', [
u('paragraph', [
u('text', 'Hello'),
u('text', ' '),
u('text', 'world!')
]),
u('blockquote', [u('paragraph', [u('text', 'First quote line')])]),
u('text', '\n'), // Newline between blocks might prevent merging without additional parsers
u('blockquote', [u('paragraph', [u('text', 'Second quote line')])])
]);
console.log('Original tree:\n', JSON.stringify(tree, null, 2));
// Compact the tree in-place
compact(tree);
console.log('\nCompacted tree:\n', JSON.stringify(tree, null, 2));
/*
Expected compacted output (exact structure may vary based on unist-builder and mdast versions,
but text nodes and blockquotes will be merged):
Compacted tree:
{
"type": "root",
"children": [
{
"type": "paragraph",
"children": [
{
"type": "text",
"value": "Hello world!"
}
]
},
{
"type": "blockquote",
"children": [
{
"type": "paragraph",
"children": [
{
"type": "text",
"value": "First quote line\nSecond quote line"
}
]
}
]
}
]
}
*/