babel-plugin-htm
raw JSON → 3.0.0 verified Sat Apr 25 auth: no javascript
A Babel plugin that compiles htm's tagged template literal syntax (html`...`) into hyperscript calls, React.createElement, Preact h, or plain VNode objects. Version 3.1.1 is current, with a slower release cadence after the major 3.0.0 rework. Unlike JSX, htm uses standard template literals, requiring no build-time syntax changes beyond this plugin. The plugin offers flexible pragma configuration, auto-import options, and experimental outputs like plain objects or monomorphic structures. It integrates with React, Preact, and any hyperscript library and supports features like static subtree caching since v3.
Common errors
error Error: Babel plugin 'htm' threw an error: Cannot find module 'htm' ↓
cause The plugin expects the 'htm' package to be installed as a peer dependency.
fix
Install htm: npm install htm
error Uncaught ReferenceError: h is not defined ↓
cause The compiled output calls h() but no hyperscript function is imported or defined.
fix
Either import a hyperscript lib (e.g., import { h } from 'preact') and set pragma: 'h', or use 'import' option to auto-import.
error SyntaxError: Unexpected template string (at ...) when using html`...` without plugin ↓
cause The browser or Node does not natively understand tagged template literal usage for HTML generation.
fix
Ensure babel-plugin-htm is configured and Babel is transpiling the code, or use htm at runtime without compilation.
Warnings
breaking In v3.0.0, the plugin no longer automatically injects the htm import. You must use the 'import' option to auto-import, or manually import htm. ↓
fix Add 'import' option to plugin config or manually import htm in your source files.
deprecated The 'pragma' option default changed from 'h' to 'React.createElement'? No, default remains 'h' but it's recommended to set it explicitly. ↓
fix Set 'pragma' option explicitly to avoid confusion: e.g., `pragma: 'h'` for Preact.
gotcha When using 'import' option with a string, the import is added only if the tag is used. If not used, no import is added, which can cause runtime errors if you expected it. ↓
fix Always ensure your code uses the tagged template with the specified tag, or manually import the pragma function.
gotcha The 'variableArity' option (default true) produces calls like h('div', null, 'text') . Setting to false produces h('div', null, ['text']). This changes children parameter type from rest args to array. ↓
fix Ensure your hyperscript function can handle both rest args and array children. With false, always pass children as array.
gotcha Setting 'useNativeSpread' to true uses object spread syntax in output, which requires Babel's object spread plugin or preset-env with appropriate targets. ↓
fix Enable @babel/plugin-proposal-object-rest-spread or use preset-env with targets supporting object spread.
Install
npm install babel-plugin-htm yarn add babel-plugin-htm pnpm add babel-plugin-htm Imports
- default (plugin) wrong
Cannot import as ES module; babel plugins are CommonJS.correctmodule.exports = { plugins: [['htm', { pragma: 'h' }]] } - html wrong
import html from 'htm'correctimport { html } from 'htm' - html from htm/preact wrong
import { html } from 'htm' (works but no Preact runtime)correctimport { html } from 'htm/preact'
Quickstart
// babel.config.js
module.exports = {
plugins: [
['htm', {
pragma: 'React.createElement',
tag: 'html',
useBuiltIns: true,
variableArity: false
}]
]
};
// src/App.jsx
import { html } from 'htm/react';
function App(props) {
return html`<div class="app"><h1>Hello, ${props.name}!</h1></div>`;
}
// Compiled output:
// import React from 'react';
// import { html as _html } from 'htm/react';
// function App(props) {
// return React.createElement("div", { class: "app" }, React.createElement("h1", null, "Hello, ", props.name, "!"));
// }