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.

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='...' />
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.
npm install htmdown
yarn add htmdown
pnpm add htmdown

Demonstrates using htmdown with React: binding to createElement, embedding expressions, and rendering with React DOM.

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));