Registry / web-framework / htm
library3.1.1jsnpmunverified

HTM (Hyperscript Tagged Markup) is a small JSX-like syntax for virtual DOM using standard JavaScript tagged templates, eliminating the need for a transpiler. Current stable version is 3.1.1, released with TypeScript module support improvements and package exports for Node 12+. It is actively maintained by the Preact team with a regular release cadence. HTM works in all modern browsers and is <600 bytes min+gzip. Key differentiators: no build step required, optional HTML-style quotes, component end-tags, HTML comments, and static subtree caching in v3. It provides off-the-shelf bindings for React and Preact, and can be customized with any hyperscript function. The package ships TypeScript type definitions, supports ESM and CJS, and can be compiled away with babel-plugin-htm for zero runtime cost in production.

npm install htm
INSTALL
IMPORT
SIG · HTM
H
htm
web-frameworkjavascriptv3.1.1
harness data pending
Install & Compatibility
Where this runs

No compatibility data collected yet for this library.

Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

default (htm function)
import htm from 'htm'
const htm = require('htm')
ESM-only since v3. CommonJS require() may work with bundlers but is not officially supported. The default export is the htm factory function, not the html tag.
html (Preact binding)
import { html } from 'htm/preact'
import html from 'htm/preact'
Default export from htm/preact is not html; it is the bind() function. Always use named import for the Preact binding.
html (React binding)
import { html } from 'htm/react'
import React from 'react'; import htm from 'htm'; const html = htm.bind(React.createElement)
While the manual bind() works, it does not share the template cache across modules. Use the pre-built htm/react binding for proper caching.
html + render (standalone)
import { html, render } from 'htm/preact/standalone'
import { html, render } from 'htm/standalone'
The standalone bundle is only available under htm/preact/standalone. It bundles both htm and Preact's core, including render, Component, and createContext.
Mini version
import htm from 'htm/mini'
import htm from 'htm/dist/mini'
The mini version (~450 bytes) supports only lowercase HTML tags. It is importable directly from 'htm/mini' since v3.

Shows how to use htm via CDN with Preact to create and render a component with dynamic content.

import { render } from 'https://unpkg.com/preact@latest?module'; import htm from 'https://unpkg.com/htm@latest?module'; const html = htm.bind(render); const App = () => html` <div class="app"> <h1>Hello, world!</h1> <p>This is completely ${'dynamic'}.</p> </div> `; render(html`<${App} />`, document.body);
Debug
Known issues
breakingIn v3.0.0, static subtree caching was introduced, which may cause components with side effects in static children not to be re-rendered.
fix
Ensure static subtrees (no dynamic values) have no side effects in render functions. If side effects are needed, add a dynamic value (e.g., a prop) to force re-evaluation.
affects: >=3.0.0
breakingHTM v3 dropped support for CommonJS require() in favor of ESM-only exports.
fix
Use ES module import syntax (import) instead of require(). If a CommonJS environment is required, use a bundler like Webpack or Rollup, or downgrade to v2.
affects: >=3.0.0
deprecatedThe htm/preact/standalone.module.js file is deprecated in favor of htm/preact/standalone (ESM) since v3.1.0.
fix
Use import { html, render } from 'htm/preact/standalone' instead of the .module.js path.
affects: >=3.1.0
gotchaSpread operators for props must use triple dots: <div ...${props}>, not <div {...props}> which is JSX-only.
fix
Use ...${props} for spreading props. For boolean attributes, just include the attribute name: <div hidden>.
affects: *
breakingHTM v2 removed support for mixed static and dynamic property values that was later re-added in v2.2.0. If upgrading from v1, ensure property concatenation works as expected.
fix
Upgrade to htm >=2.2.0 or use a transpiler like babel-plugin-htm for consistent behavior.
affects: >=2.0.0 <2.2.0
Errors
Common errors & fixes
TypeError: htm is not a function
Using default import from 'htm' but htm returns a factory function that must be bound to a hyperscript function.
fix
const html = htm.bind(React.createElement);
Uncaught SyntaxError: The requested module 'https://unpkg.com/htm?module' does not provide an export named 'html'
Trying to import { html } from the base 'htm' package, but 'html' is only available from 'htm/preact' or 'htm/react'.
fix
Use import htm from 'https://unpkg.com/htm?module' and then const html = htm.bind(React.createElement); or import { html } from 'https://unpkg.com/htm/preact?module'.
Error: [htm] Could not find module 'preact'
Using htm/preact without preact installed or available in the module graph.
fix
Install preact: npm install preact
Warning: Each child in a list should have a unique 'key' prop.
HTM does not automatically add key props when rendering arrays. JSX-style key attribute is required.
fix
Add a key attribute to list items: <li key=${item.id}>${item.name}</li>
Upgrade
Version history
3.1.1latest on npm
Audit
Dependencies
preactoptionalRequired when using htm/preact or htm/preact/standalone bindings
reactoptionalRequired when using htm/react bindings
Agent activity
6 hits · last 30 days
node
6
Resources