What is JSX?
JSX allows you to write UI components using familiar HTML syntax:How JSX works
JSX is not valid JavaScript. It must be transformed by a compiler (like Babel or TypeScript) into function calls.The createElement function
Preact’screateElement() function (aliased as h()) converts JSX into VNodes (src/create-element.js:16):
JSX transformation
This JSX:The
h function is Preact’s alias for createElement, inspired by hyperscript conventions.Configuring JSX
You need to configure your build tool to transform JSX and specify Preact as the JSX factory.Babel configuration
Add the React JSX transform plugin to your.babelrc or babel.config.js:
h in every file that uses JSX:
TypeScript configuration
Configure TypeScript in yourtsconfig.json:
tsconfig.json
TypeScript requires you to import
h even if you don’t use it directly, as it’s referenced in the transpiled output.Automatic JSX runtime
Modern build tools support the automatic JSX runtime, which eliminates the need to importh:
- Babel
- TypeScript
- esbuild
.babelrc
JSX expressions
You can embed any JavaScript expression in JSX using curly braces:Conditional rendering
JSX attributes
JSX attributes use camelCase naming, except fordata-* and aria-* attributes:
Special attributes
Preact handles several attributes specially:className- Sets the element’s CSS classstyle- Accepts an object of CSS propertiesdangerouslySetInnerHTML- Sets raw HTML (use with caution)key- Helps Preact identify elements in listsref- Gets a reference to the DOM node
Children
Everything between an opening and closing tag becomes thechildren prop:
- Strings and numbers
- JSX elements
- Arrays of elements
- Functions (render props)
null,undefined, orfalse(renders nothing)
Fragments
Fragments let you group multiple elements without adding extra DOM nodes (src/create-element.js:77):
Using fragments
- Fragment component
- Short syntax
The
<> short syntax requires configuring your build tool to recognize it as a Fragment.Lists and keys
When rendering lists, each element should have a uniquekey prop:
Real-world example
Here’s a complete example from Preact’s demo (demo/index.jsx:68):
- Class component with JSX
- Props destructuring in render
- Nested JSX elements
- Component composition
- Conditional rendering via Router
JSX gotchas
Self-closing tags
Always close tags, even for elements that don’t have children:JavaScript reserved words
Some HTML attributes conflict with JavaScript keywords:- Use
classNameinstead ofclass - Use
htmlForinstead offor