hastscript: Hyperscript for HAST Trees
hastscript is a utility library that provides a hyperscript interface for programmatically creating HTML Abstract Syntax Trees (hast trees). Analogous to React's `createElement` or Vue's `h` function, it simplifies the process of generating complex HTML structures in code by replacing repetitive object literal syntax with concise function calls. It also handles the normalization of attributes into the format required by the hast specification. The current stable version is 9.0.1, with frequent patch and minor releases and major versions typically introducing breaking changes like ESM-only support or Node.js version bumps. It is a core part of the unified ecosystem for processing content and specifically targets HTML, differentiating it from `unist-builder` (for generic unist nodes) or `xastscript` (for XML nodes).
Common errors
-
Error [ERR_REQUIRE_ESM]: require() of ES Module .../node_modules/hastscript/index.js from ... not supported.
cause Attempting to import `hastscript` using CommonJS `require()` syntax when the package is ESM-only.fixChange your import statements to use ESM syntax: `import { h } from 'hastscript';` and ensure your environment supports ESM (e.g., `"type": "module"` in `package.json`). -
TypeError: Cannot read properties of undefined (reading 'h')
cause This usually indicates an incorrect CommonJS `require()` of a named export from an ESM package, or a failure to import correctly.fixEnsure you are using `import { h } from 'hastscript';` for ESM, or if in a strict CommonJS context (not recommended for `hastscript`), use `import('hastscript').then(({ h }) => { /* ... */ });`. -
Module not found: Error: Can't resolve 'hastscript/html' in '...'
cause Attempting to import from `hastscript/html` or `hastscript/svg` subpaths, which were removed in version 8.0.0.fixUpdate your imports to `import { h, s } from 'hastscript';` as both functions are now directly exported from the main package entry point. -
SyntaxError: Must use import to load ES Module: .../node_modules/hastscript/index.js
cause You are trying to `require()` an ESM module in a context that does not allow it (e.g., an older Node.js version, or a CJS file trying to load ESM directly).fixUpgrade Node.js to a version that supports ESM (>=16 for hastscript) and ensure your files are treated as ESM, or use dynamic `import()` if necessary.
Warnings
- breaking hastscript switched to being an ESM-only package. CommonJS users must migrate to `import` statements or use dynamic `import()`.
- breaking Node.js 16 or higher is now required for `hastscript`.
- breaking The subpath exports `hastscript/html` and `hastscript/svg` were removed. Both HTML and SVG functions (`h` and `s`) are now directly available from the main `hastscript` export.
- breaking Better custom element support was added by tightening overload detection, which has a tiny chance of breaking existing code if you were relying on previous, more lenient behavior with custom elements.
- breaking TypeScript types were introduced, which could be a potentially breaking change if you or your dependents are using TypeScript in a specific way that conflicts with the new types.
- gotcha When using `hastscript` as a JSX pragma, ensure your build tool (e.g., TypeScript, Babel) is configured to use `hastscript` or `hastscript/svg` as the `importSource` for the automatic JSX runtime.
Install
-
npm install hastscript -
yarn add hastscript -
pnpm add hastscript
Imports
- h
const { h } = require('hastscript')import { h } from 'hastscript' - s
const { s } = require('hastscript')import { s } from 'hastscript' - Child, Properties, Result
import type { Child, Properties, Result } from 'hastscript'
Quickstart
import {h, s} from 'hastscript';
const htmlTree = h('.foo#some-id', [
h('span', 'some text'),
h('input', {type: 'text', value: 'foo'}),
h('a.alpha', {class: 'bravo charlie', download: 'download'}, [
'delta',
'echo'
])
]);
const svgTree = s('svg', {viewbox: '0 0 500 500', xmlns: 'http://www.w3.org/2000/svg'}, [
s('title', 'SVG `<circle>` element'),
s('circle', {cx: 120, cy: 120, r: 100})
]);
console.log('HTML Tree:', JSON.stringify(htmlTree, null, 2));
console.log('SVG Tree:', JSON.stringify(svgTree, null, 2));