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.

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.
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.
npm install babel-plugin-htm
yarn add babel-plugin-htm
pnpm add babel-plugin-htm

Shows how to configure babel-plugin-htm with React pragma, use built-ins, fixed arity, and compile a tagged template component.

// 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, "!"));
// }