Bun supports `.jsx` and `.tsx` files out of the box. Bun's internal transpiler converts JSX syntax into vanilla JavaScript before execution. ```tsx#react.tsx function Component(props: {message: string}) { return (

{props.message}

); } console.log(); ``` ## Configuration Bun reads your `tsconfig.json` or `jsconfig.json` configuration files to determines how to perform the JSX transform internally. To avoid using either of these, the following options can also be defined in [`bunfig.json`](/docs/runtime/configuration). The following compiler options are respected. ### [`jsx`](https://www.typescriptlang.org/tsconfig#jsx) How JSX constructs are transformed into vanilla JavaScript internally. The table below lists the possible values of `jsx`, along with their transpilation of the following simple JSX component: ```tsx Hello ``` {% table %} - Compiler options - Transpiled output --- - ```json { "jsx": "react" } ``` - ```tsx import { createElement } from "react"; createElement("Box", { width: 5 }, "Hello"); ``` --- - ```json { "jsx": "react-jsx" } ``` - ```tsx import { jsx } from "react/jsx-runtime"; jsx("Box", { width: 5 }, "Hello"); ``` --- - ```json { "jsx": "react-jsxdev" } ``` - ```tsx import { jsxDEV } from "react/jsx-dev-runtime"; jsxDEV( "Box", { width: 5, children: "Hello" }, undefined, false, undefined, this, ); ``` The `jsxDEV` variable name is a convention used by React. The `DEV` suffix is a visible way to indicate that the code is intended for use in development. The development version of React is slowers and includes additional validity checks & debugging tools. --- - ```json { "jsx": "preserve" } ``` - ```tsx // JSX is not transpiled // "preserve" is not supported by Bun currently Hello ``` {% /table %} ### [`jsxFactory`](https://www.typescriptlang.org/tsconfig#jsxFactory) {% callout %} **Note** — Only applicable when `jsx` is `react`. {% /callout %} The function name used to represent JSX constructs. Default value is `"createElement"`. This is useful for libraries like [Preact](https://preactjs.com/) that use a different function name (`"h"`). {% table %} - Compiler options - Transpiled output --- - ```json { "jsx": "react", "jsxFactory": "h" } ``` - ```tsx import { h } from "react"; h("Box", { width: 5 }, "Hello"); ``` {% /table %} ### [`jsxFragmentFactory`](https://www.typescriptlang.org/tsconfig#jsxFragmentFactory) {% callout %} **Note** — Only applicable when `jsx` is `react`. {% /callout %} The function name used to represent [JSX fragments](https://react.dev/reference/react/Fragment) such as `<>Hello`; only applicable when `jsx` is `react`. Default value is `"Fragment"`. {% table %} - Compiler options - Transpiled output --- - ```json { "jsx": "react", "jsxFactory": "myjsx", "jsxFragmentFactory": "MyFragment" } ``` - ```tsx // input <>Hello; // output import { myjsx, MyFragment } from "react"; createElement("Box", { width: 5 }, "Hello"); ``` {% /table %} ### [`jsxImportSource`](https://www.typescriptlang.org/tsconfig#jsxImportSource) {% callout %} **Note** — Only applicable when `jsx` is `react-jsx` or `react-jsxdev`. {% /callout %} The module from which the component factory function (`createElement`, `jsx`, `jsxDEV`, etc) will be imported. Default value is `"react"`. This will typically be necessary when using a component library like Preact. {% table %} - Compiler options - Transpiled output --- - ```jsonc { "jsx": "react" // jsxImportSource is not defined // default to "react" } ``` - ```tsx import { jsx } from "react/jsx-runtime"; jsx("Box", { width: 5, children: "Hello" }); ``` --- - ```jsonc { "jsx": "react-jsx", "jsxImportSource": "preact" } ``` - ```tsx import { jsx } from "preact/jsx-runtime"; jsx("Box", { width: 5, children: "Hello" }); ``` --- - ```jsonc { "jsx": "react-jsxdev", "jsxImportSource": "preact" } ``` - ```tsx // /jsx-runtime is automatically appended import { jsxDEV } from "preact/jsx-dev-runtime"; jsxDEV( "Box", { width: 5, children: "Hello" }, undefined, false, undefined, this, ); ``` {% /table %} ### JSX pragma All of these values can be set on a per-file basis using _pragmas_. A pragma is a special comment that sets a compiler option in a particular file. {% table %} - Pragma - Equivalent config --- - ```ts // @jsx h ``` - ```jsonc { "jsxFactory": "h" } ``` --- - ```ts // @jsxFrag MyFragment ``` - ```jsonc { "jsxFragmentFactory": "MyFragment" } ``` --- - ```ts // @jsxImportSource preact ``` - ```jsonc { "jsxImportSource": "preact" } ``` {% /table %} ## Logging Bun implements special logging for JSX to make debugging easier. Given the following file: ```tsx#index.tsx import { Stack, UserCard } from "./components"; console.log( ); ``` Bun will pretty-print the component tree when logged: {% image src="https://github.com/oven-sh/bun/assets/3084745/d29db51d-6837-44e2-b8be-84fc1b9e9d97" / %} ## Prop punning The Bun runtime also supports "prop punning" for JSX. This is a shorthand syntax useful for assigning a variable to a prop with the same name. ```tsx function Div(props: {className: string;}) { const {className} = props; // without punning return
; // with punning return
; } ```