hast-util-from-html

A hast utility that parses serialized HTML into a syntax tree using parse5, with detailed error reporting.

Library
npm
v2.0.3
41stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
27/100Needs Attention
Development Activity0
Maintenance20
Community20
Maturity56
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
81/100Excellent
Architecture82
Code Quality88
Innovation68
Learning Curve85

hast-util-from-html is a small utility from the syntax-tree/unified ecosystem that turns raw HTML strings into a hast (HTML Abstract Syntax Tree) syntax tree. Internally it wraps parse5, the spec-compliant HTML parser, and passes the resulting document through hast-util-from-parse5 to produce a hast Root node with positional information attached to every node.

Beyond basic parsing, the package exposes fine-grained control over the roughly 60 categories of HTML parse errors defined by the WHATWG HTML spec — each can be turned off, treated as a warning, or escalated to a fatal error via an onerror callback that receives a VFileMessage. It supports both full-document and fragment parsing modes, and can parse content in the SVG namespace embedded within HTML. It is the core parsing layer that powers rehype-parse and the wider rehype/unified toolchain used to build markdown and HTML processing pipelines.

What You Get

  • A single fromHtml(value, options) function that returns a hast Root node from an HTML string, Buffer, or VFile
  • Support for both full-document parsing and fragment: true parsing for HTML snippets
  • Configurable handling of ~60 distinct WHATWG parse-error codes, each settable to off/warning/fatal
  • An onerror callback that receives structured VFileMessage objects with source location, severity, and a spec URL for every parse error
  • Automatic HTML-to-SVG namespace switching when an <svg> element is encountered
  • Complete TypeScript types for Options, ErrorCode, and ErrorSeverity, generated from JSDoc and checked with 100% type coverage

Common Use Cases

  • Powering rehype-parse, the entry point for rehype/unified pipelines that transform or lint HTML
  • Parsing HTML fragments pulled from a CMS or user input into an AST for sanitization with hast-util-sanitize
  • Building custom static-site or documentation tooling that needs a positioned AST instead of a DOM
  • Linting or auditing HTML documents by surfacing every WHATWG parse error with location and severity
  • Converting HTML into hast so it can be transformed and re-serialized with hast-util-to-html

Under The Hood

Architecture The package is a thin, single-purpose orchestration layer: lib/index.js exports one function, fromHtml, which wraps value in a VFile if needed, chooses parse5’s parse or parseFragment based on options.fragment, and pipes the resulting parse5 document through hast-util-from-parse5 to produce a hast Root. Parse-error handling is implemented as a closure (internalOnerror) passed to parse5’s onParseError hook, which looks up each error code in a large static errors table (lib/errors.js), applies the caller’s configured severity, formats the human-readable message (substituting %c/%x placeholders with the offending character), and constructs a VFileMessage with precise start/end positions before invoking the caller’s onerror. There is no internal state beyond this single call — the module has no classes, no caching, and nothing would break elsewhere if the core abstraction changed, since it is a leaf dependency consumed by exactly one call path (rehype-parse and direct callers).

Tech Stack Written in plain ESM JavaScript with JSDoc-based typing (no .ts source; declarations are emitted via tsc --build and checked with type-coverage at 100%). Runtime dependencies are parse5 (the HTML parser), hast-util-from-parse5 (parse5-to-hast conversion), vfile/vfile-message (file and diagnostic wrappers from the unified ecosystem), @types/hast, and devlop for lightweight runtime assertions. Build and quality tooling includes xo (ESLint preset) and prettier for formatting/linting, remark-cli with remark-preset-wooorm for markdown/readme linting, and c8 for coverage. CI runs on GitHub Actions across a matrix of Node versions with npm test, uploading coverage to Codecov.

Code Quality Tests live in test/index.js using Node’s built-in node:test and node:assert/strict — no external test framework. Assertions are deep structural comparisons of the full hast tree the function returns, plus dedicated fixture-driven tests for each parse-error code under test/parse-error/. The project enforces 100% test coverage via c8 --100 and 100% type coverage via type-coverage, both wired into the test script so a regression on either fails CI. Error handling is explicit throughout — internalOnerror uses devlop’s assert to fail loudly on unexpected internal states rather than swallowing them. Naming and formatting are enforced by xo/prettier with no manual style drift.

What Makes It Unique Most HTML-to-AST bridges expose parsing as an all-or-nothing operation; this package instead exposes the full WHATWG catalog of parse errors as individually configurable diagnostics with source positions and spec links, letting callers treat malformed HTML as lintable data rather than a binary parse failure. Combined with automatic SVG-namespace switching mid-document, it gives the unified/rehype ecosystem a parsing layer that is both spec-accurate and introspectable, which is why it underpins rehype-parse rather than being replaced by a simpler wrapper.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search