# hast-util-to-jsx-runtime
[![Build][badge-build-image]][badge-build-url]
[![Coverage][badge-coverage-image]][badge-coverage-url]
[![Downloads][badge-downloads-image]][badge-downloads-url]
[![Size][badge-size-image]][badge-size-url]
hast utility to transform a tree to
preact, react, solid, svelte, vue, etcetera,
with an automatic JSX runtime.
## Contents
* [What is this?](#what-is-this)
* [When should I use this?](#when-should-i-use-this)
* [Install](#install)
* [Use](#use)
* [API](#api)
* [`toJsxRuntime(tree, options)`](#tojsxruntimetree-options)
* [`Components`](#components)
* [`CreateEvaluater`](#createevaluater)
* [`ElementAttributeNameCase`](#elementattributenamecase)
* [`EvaluateExpression`](#evaluateexpression)
* [`EvaluateProgram`](#evaluateprogram)
* [`Evaluater`](#evaluater)
* [`ExtraProps`](#extraprops)
* [`Fragment`](#fragment)
* [`Jsx`](#jsx)
* [`JsxDev`](#jsxdev)
* [`Options`](#options)
* [`Props`](#props)
* [`Source`](#source)
* [`Space`](#space)
* [`StylePropertyNameCase`](#stylepropertynamecase)
* [Errors](#errors)
* [Examples](#examples)
* [Example: Preact](#example-preact)
* [Example: Solid](#example-solid)
* [Example: Svelte](#example-svelte)
* [Example: Vue](#example-vue)
* [Syntax](#syntax)
* [Compatibility](#compatibility)
* [Security](#security)
* [Related](#related)
* [Contribute](#contribute)
* [License](#license)
## What is this?
This package is a utility that takes a [hast][github-hast] tree and an
[automatic JSX runtime][reactjs-jsx-runtime] and turns the tree into anything
you wish.
## When should I use this?
You can use this package when you have a hast syntax tree and want to use it
with whatever framework.
This package uses an automatic JSX runtime,
which is a sort of lingua franca for frameworks to support JSX.
Notably,
automatic runtimes have support for passing extra information in development,
and have guaranteed support for fragments.
## Install
This package is [ESM only][github-gist-esm].
In Node.js (version 16+),
install with [npm][npmjs-install]:
```sh
npm install hast-util-to-jsx-runtime
```
In Deno with [`esm.sh`][esmsh]:
```js
import {toJsxRuntime} from 'https://esm.sh/hast-util-to-jsx-runtime@2'
```
In browsers with [`esm.sh`][esmsh]:
```html
```
## Use
```js
import {h} from 'hastscript'
import {toJsxRuntime} from 'hast-util-to-jsx-runtime'
import {Fragment, jsxs, jsx} from 'react/jsx-runtime'
import {renderToStaticMarkup} from 'react-dom/server'
const tree = h('h1', 'Hello, world!')
const doc = renderToStaticMarkup(toJsxRuntime(tree, {Fragment, jsxs, jsx}))
console.log(doc)
```
Yields:
```html
Hello, world!
```
> **Note**:
> to add better type support,
> register a global JSX namespace:
>
> ```ts
> import type {JSX as Jsx} from 'react/jsx-runtime'
>
> declare global {
> namespace JSX {
> type ElementClass = Jsx.ElementClass
> type Element = Jsx.Element
> type IntrinsicElements = Jsx.IntrinsicElements
> }
> }
> ```
## API
This package exports the identifier [`toJsxRuntime`][api-to-jsx-runtime].
It exports the [TypeScript][] types
[`Components`][api-components],
[`CreateEvaluater`][api-create-evaluater],
[`ElementAttributeNameCase`][api-element-attribute-name-case],
[`EvaluateExpression`][api-evaluate-expression],
[`EvaluateProgram`][api-evaluate-program],
[`Evaluater`][api-evaluater],
[`ExtraProps`][api-extra-props],
[`Fragment`][api-fragment],
[`Jsx`][api-jsx],
[`JsxDev`][api-jsx-dev],
[`Options`][api-options],
[`Props`][api-props],
[`Source`][api-source],
[`Space`][api-Space],
and
[`StylePropertyNameCase`][api-style-property-name-case].
There is no default export.
### `toJsxRuntime(tree, options)`
Transform a hast tree to
preact, react, solid, svelte, vue, etcetera,
with an automatic JSX runtime.
##### Parameters
* `tree`
([`Node`][github-hast-nodes])
— tree to transform
* `options`
([`Options`][api-options], required)
— configuration
##### Returns
Result from your configured JSX runtime
(`JSX.Element` if defined,
otherwise `unknown` which you can cast yourself).
### `Components`
Possible components to use (TypeScript type).
Each key is a tag name typed in `JSX.IntrinsicElements`,
if defined.
Each value is either a different tag name
or a component accepting the corresponding props
(and an optional `node` prop if `passNode` is on).
You can access props at `JSX.IntrinsicElements`.
For example,
to find props for `a`,
use `JSX.IntrinsicElements['a']`.
###### Type
```ts
import type {Element} from 'hast'
type ExtraProps = {node?: Element | undefined}
type Components = {
[TagName in keyof JSX.IntrinsicElements]:
| Component
| keyof JSX.IntrinsicElements
}
type Component =
// Class component:
| (new (props: ComponentProps) => JSX.ElementClass)
// Function component:
| ((props: ComponentProps) => JSX.Element | string | null | undefined)
```
### `CreateEvaluater`
Create an evaluator that turns ESTree ASTs from embedded MDX into values
(TypeScript type).
###### Parameters
There are no parameters.
###### Returns
Evaluater ([`Evaluater`][api-evaluater]).
### `ElementAttributeNameCase`
Casing to use for attribute names (TypeScript type).
HTML casing is for example
`class`, `stroke-linecap`, `xml:lang`.
React casing is for example
`className`, `strokeLinecap`, `xmlLang`.
###### Type
```ts
type ElementAttributeNameCase = 'html' | 'react'
```
### `EvaluateExpression`
Turn an MDX expression into a value (TypeScript type).
###### Parameters
* `expression` (`Expression` from `@types/estree`)
— estree expression
###### Returns
Result of expression (`unknown`).
### `EvaluateProgram`
Turn an MDX program (export/import statements) into a value (TypeScript type).
###### Parameters
* `program` (`Program` from `@types/estree`)
— estree program
###### Returns
Result of program (`unknown`);
should likely be `undefined` as ESM changes the scope but doesn’t yield
something.
### `Evaluater`
Evaluator that turns ESTree ASTs from embedded MDX into values (TypeScript
type).
###### Fields
* `evaluateExpression` ([`EvaluateExpression`][api-evaluate-expression])
— evaluate an expression
* `evaluateProgram` ([`EvaluateProgram`][api-evaluate-program])
— evaluate a program
### `ExtraProps`
Extra fields we pass (TypeScript type).
###### Type
```ts
type ExtraProps = {node?: Element | undefined}
```
### `Fragment`
Represent the children,
typically a symbol (TypeScript type).
###### Type
```ts
type Fragment = unknown
```
### `Jsx`
Create a production element (TypeScript type).
###### Parameters
* `type` (`unknown`)
— element type:
`Fragment` symbol,
tag name (`string`),
component
* `props` ([`Props`][api-props])
— element props,
`children`,
and maybe `node`
* `key` (`string` or `undefined`)
— dynamicly generated key to use
###### Returns
Element from your framework
(`JSX.Element` if defined,
otherwise `unknown` which you can cast yourself).
### `JsxDev`
Create a development element (TypeScript type).
###### Parameters
* `type` (`unknown`)
— element type:
`Fragment` symbol,
tag name (`string`),
component
* `props` ([`Props`][api-props])
— element props,
`children`,
and maybe `node`
* `key` (`string` or `undefined`)
— dynamicly generated key to use
* `isStaticChildren` (`boolean`)
— whether two or more children are passed (in an array),
which is whether `jsxs` or `jsx` would be used
* `source` ([`Source`][api-source])
— info about source
* `self` (`undefined`)
— nothing (this is used by frameworks that have components,
we don’t)
###### Returns
Element from your framework
(`JSX.Element` if defined,
otherwise `unknown` which you can cast yourself).
### `Options`
Configuration (TypeScript type).
###### Fields
* `Fragment` ([`Fragment`][api-fragment], required)
— fragment
* `jsxDEV` ([`JsxDev`][api-jsx-dev], required in development)
— development JSX
* `jsxs` ([`Jsx`][api-jsx], required in production)
— static JSX
* `jsx` ([`Jsx`][api-jsx], required in production)
— dynamic JSX
* `components` ([`Partial`][api-components], optional)
— components to use
* `createEvaluater` ([`CreateEvaluater`][api-create-evaluater], optional)
— create an evaluator that turns ESTree ASTs into values
* `development` (`boolean`, default: `false`)
— whether to use `jsxDEV` when on or `jsx` and `jsxs` when off
* `elementAttributeNameCase`
([`ElementAttributeNameCase`][api-element-attribute-name-case],
default: `'react'`)
— specify casing to use for attribute names
* `filePath` (`string`, optional)
— file path to the original source file,
passed in source info to `jsxDEV` when using the automatic runtime with
`development: true`
* `passNode` (`boolean`, default: `false`)
— pass the hast element node to components
* `space` ([`Space`][api-space], default: `'html'`)
— whether `tree` is in the `'html'` or `'svg'` space, when an `