htmdown
raw JSON → 0.1.0 verified Fri May 01 auth: no javascript
htmdown is an MDX-like syntax library for plain JavaScript using tagged template literals, built on top of htm. Current stable version is 0.1.0. It allows embedding JSX-like expressions in Markdown without a transpiler, leveraging the htm library for template-based virtual DOM creation. It ships TypeScript definitions. Key differentiators: no build step, works with React and Preact, and uses standard ES6 template literals. Released at a low cadence, it is a minimal utility for small projects or prototypes.
Common errors
error Uncaught TypeError: htmdown is not a function ↓
cause Attempting to use require() in an ESM context or calling htmdown directly without .bind().
fix
Ensure you use import (not require) and bind to a createElement: const md = htmdown.bind(React.createElement);
error Module not found: Can't resolve 'htm' ↓
cause Missing peer dependency htm.
fix
Run: npm install htm
error JSX element 'img' has no corresponding closing tag ↓
cause Using unclosed tags like <img src='...'> instead of self-closing <img src='...'/>.
fix
Always self-close void elements: <img src='...' />
Warnings
gotcha htmdown must be bound to a createElement function before use. Forgetting .bind(createElement) will cause a runtime error. ↓
fix Call const md = htmdown.bind(React.createElement); before using md`...`.
gotcha HTM is a peer dependency and must be installed explicitly. Skipping npm i htm will cause a missing module error. ↓
fix Run npm i htm alongside htmdown.
gotcha HTML elements must be closed. Self-closing tags like <br/> are required; <br> is invalid and will throw. ↓
fix Use <br/> instead of <br> inside template literals.
gotcha Only one root element per template literal is allowed. Multiple sibling elements will cause undefined behavior. ↓
fix Wrap multiple elements in a single parent, e.g., div or fragment.
gotcha Expressions inside code blocks (backticks) are not parsed; they are treated as literal strings. ↓
fix Use the syntax normally; it's by design.
Install
npm install htmdown yarn add htmdown pnpm add htmdown Imports
- default wrong
const htmdown = require('htmdown')correctimport htmdown from 'htmdown' - htmdown wrong
import { htmdown } from 'htmdown'correctimport htmdown from 'htmdown'; const md = htmdown.bind(createElement) - TypeScript usage wrong
const md: any = htmdown.bind(createElement) // missing typecorrectimport htmdown from 'htmdown'; const md: (strings: TemplateStringsArray, ...values: any[]) => ReturnType<typeof htmdown> = htmdown.bind(createElement)
Quickstart
import htmdown from 'htmdown';
import { createElement, render } from 'react';
import { createRoot } from 'react-dom/client';
const md = htmdown.bind(createElement);
function App() {
const name = 'World';
return md`
# Hello ${name}
This is **htmdown** in action!
<button onClick={() => alert('Hi!')}>Click me</button>
`;
}
const root = createRoot(document.getElementById('root'));
root.render(createElement(App));