{"id":11017,"library":"hast-util-to-mdast","title":"HAST to MDAST Transformer Utility","description":"hast-util-to-mdast is a core utility within the unified.js ecosystem designed to transform a HAST (HTML Abstract Syntax Tree) into an MDAST (Markdown Abstract Syntax Tree). This package is essential for converting HTML content into Markdown programmatically, often serving as the engine behind higher-level plugins like `rehype-remark`. The current stable version is 10.1.2. The package maintains an active release cadence, with frequent patch and minor updates addressing bug fixes and feature enhancements, alongside major versions that typically align with Node.js LTS updates or significant API refinements. Key differentiators include its tight integration with the unified ecosystem, robust handling of various HTML structures, and the provision of a flexible API with custom handlers for fine-grained control over the transformation process, allowing developers to define how specific HTML elements or nodes should be represented in Markdown.","status":"active","version":"10.1.2","language":"javascript","source_language":"en","source_url":"https://github.com/syntax-tree/hast-util-to-mdast","tags":["javascript","hast-util","hast","html","markdown","mdast-util","mdast","rehype","remark","typescript"],"install":[{"cmd":"npm install hast-util-to-mdast","lang":"bash","label":"npm"},{"cmd":"yarn add hast-util-to-mdast","lang":"bash","label":"yarn"},{"cmd":"pnpm add hast-util-to-mdast","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core AST specification for HTML, used as input tree type.","package":"hast","optional":false},{"reason":"Core AST specification for Markdown, used as output tree type.","package":"mdast","optional":false},{"reason":"Commonly used to parse HTML strings into a HAST tree before passing to hast-util-to-mdast.","package":"hast-util-from-html","optional":true},{"reason":"Commonly used to serialize the resulting MDAST tree back into a Markdown string.","package":"mdast-util-to-markdown","optional":true},{"reason":"A rehype plugin that wraps this utility, providing a higher-level abstraction for HTML-to-Markdown conversion within a unified pipeline.","package":"rehype-remark","optional":true}],"imports":[{"note":"This package is ESM-only since v10.0.0. CommonJS `require` will not work.","wrong":"const toMdast = require('hast-util-to-mdast')","symbol":"toMdast","correct":"import { toMdast } from 'hast-util-to-mdast'"},{"note":"Provides the default handling logic for HTML elements, useful for extending or overriding behavior with custom handlers.","symbol":"defaultHandlers","correct":"import { defaultHandlers } from 'hast-util-to-mdast'"},{"note":"TypeScript type for the state object passed to handlers, essential when implementing custom transformation logic. Import with `type` keyword.","symbol":"State","correct":"import type { State } from 'hast-util-to-mdast'"}],"quickstart":{"code":"import fs from 'node:fs/promises';\nimport { fromHtml } from 'hast-util-from-html';\nimport { toMdast } from 'hast-util-to-mdast';\nimport { toMarkdown } from 'mdast-util-to-markdown';\n\nasync function convertHtmlToMarkdown(htmlString: string): Promise<string> {\n  // Parse the HTML string into a HAST (HTML Abstract Syntax Tree) fragment.\n  const hast = fromHtml(htmlString, { fragment: true });\n\n  // Transform the HAST tree into an MDAST (Markdown Abstract Syntax Tree).\n  const mdast = toMdast(hast);\n\n  // Serialize the MDAST tree back into a Markdown string.\n  const markdown = toMarkdown(mdast);\n\n  return markdown;\n}\n\n// Example usage:\nconst exampleHtml = '<h2>Hello <strong>world!</strong></h2><p>This is a paragraph with a <a href=\"#\">link</a> and a <br>line break.</p>';\n\nconvertHtmlToMarkdown(exampleHtml)\n  .then(markdown => {\n    console.log('Original HTML:\\n', exampleHtml);\n    console.log('\\nConverted Markdown:\\n', markdown);\n  })\n  .catch(error => {\n    console.error('Conversion failed:', error);\n  });\n\n// To show an actual file read (requires 'example.html' file):\n// const htmlFilePath = './example.html';\n// try {\n//   const fileHtml = await fs.readFile(htmlFilePath, 'utf8');\n//   const convertedFileMarkdown = await convertHtmlToMarkdown(fileHtml);\n//   console.log(`\\nMarkdown from ${htmlFilePath}:\\n`, convertedFileMarkdown);\n// } catch (err) {\n//   console.error(`Could not read file ${htmlFilePath}:`, err);\n// }\n","lang":"typescript","description":"Demonstrates how to convert an HTML string to Markdown using `hast-util-from-html`, `hast-util-to-mdast`, and `mdast-util-to-markdown`."},"warnings":[{"fix":"Ensure your project uses Node.js v16.0.0 or higher. Update your Node.js runtime if necessary.","message":"Version 10.0.0 introduced a breaking change requiring Node.js 16 or later. Previous versions (9.x) supported Node.js 14.14+ or later, and earlier versions supported Node.js 12+.","severity":"breaking","affected_versions":">=10.0.0"},{"fix":"Refactor your imports to use ESM syntax (e.g., `import { toMdast } from 'hast-util-to-mdast'`). If your project is still CommonJS, consider transpilation or upgrading your project to use ESM.","message":"Since version 10.0.0, this package is ESM-only (ECMAScript Modules). The 'exports' field was added to `package.json`, making CommonJS `require()` incompatible.","severity":"breaking","affected_versions":">=10.0.0"},{"fix":"If you are using custom handlers, consult the official documentation for the new API. You will need to rewrite your handler functions to use the `state` object and its methods (e.g., `state.one`, `state.all`).","message":"Version 9.0.0 significantly changed the API for custom handlers. The `h` parameter was replaced with a more powerful `state` object, and the `one` and `all` exports were removed in favor of `state.one` and `state.all`.","severity":"breaking","affected_versions":">=9.0.0 <10.0.0"},{"fix":"Update to `hast-util-to-mdast@10.1.2` or later to ensure `br` elements are correctly preserved in phrasing content.","message":"Prior to version 10.1.2, `br` (line break) elements within phrasing content could be unexpectedly dropped during the transformation process, leading to a loss of intended layout.","severity":"gotcha","affected_versions":"<10.1.2"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Change `const { toMdast } = require('hast-util-to-mdast');` to `import { toMdast } from 'hast-util-to-mdast';`. Ensure your project's `package.json` includes `\"type\": \"module\"` or uses `.mjs` files for ESM.","cause":"Attempting to use `require()` to import `hast-util-to-mdast` in a project configured for ESM, or after upgrading to v10+ in a CommonJS project.","error":"TypeError: require is not a function in ES module scope"},{"fix":"These functions are no longer direct exports. When implementing custom handlers, access them via the `state` object passed to your handler: `state.one(node, parent)` and `state.all(node, parent)`.","cause":"You've upgraded from a version prior to 9.0.0 to 9.0.0 or later and are still trying to import or use `one` or `all` functions directly.","error":"TypeError: Cannot read properties of undefined (reading 'one') or (reading 'all')"},{"fix":"Upgrade your Node.js runtime environment to version 16 or newer. Use `nvm install 16` (or higher) and `nvm use 16` if using Node Version Manager.","cause":"Running `hast-util-to-mdast` version 10.0.0 or higher on an unsupported Node.js version (e.g., Node.js 14).","error":"Error: This package now requires Node.js 16. Please upgrade your Node.js version."}],"ecosystem":"npm"}