HTML to JSX Converter
Paste HTML and get clean JSX you can drop into a React component. Attributes are renamed, inline styles become style objects, void tags are self-closed, comments and event handlers are converted, and SVG attributes are camelCased.
How to use the HTML to JSX Converter
- Paste your HTML into the left box, or load the sample. A full page works too: the body content is converted.
- Choose the output: plain JSX or a complete React function component with a name of your choice.
- Set the options for comments, event handlers, uncontrolled form fields and self-closing empty tags.
- Review the JSX on the right and the list of changes below it. It updates as you type.
- Copy or download the result as a .jsx file.
HTML vs JSX: what gets converted
| HTML | JSX | Why |
|---|---|---|
class="btn" | className="btn" | class is a reserved word in JavaScript |
<label for="email"> | <label htmlFor="email"> | for is a reserved word |
tabindex="0" maxlength="80" | tabIndex="0" maxLength="80" | DOM properties are camelCase |
style="font-size: 12px; z-index: 10" | style={{ fontSize: '12px', zIndex: 10 }} | style takes a JavaScript object |
<br>, <img src="a.png"> | <br />, <img src="a.png" /> | Every JSX tag must be closed |
<!-- note --> | {/* note */} | JSX has no HTML comments |
onclick="save()" | onClick={() => save()} | Handlers are functions, not strings |
stroke-width="2" (SVG) | strokeWidth="2" | React uses camelCase SVG attributes |
<input value="x"> | <input defaultValue="x" /> | Keeps the field editable without state |
Hello {name} (text) | Hello {'{'}name{'}'} | Braces start JavaScript expressions in JSX |
| Sibling elements | <>…</> | A component returns a single root |
Attributes that stay the same
data-* and aria-* attributes keep their hyphenated, lowercase names in React, so aria-label and data-id are copied unchanged. Most other attributes are already single words (id, href, src, alt, type, name) and need no change. Boolean attributes written without a value, such as disabled or required, become JSX shorthand for ={true}.
After converting: tips
- Move logic out of the markup. Converted event handlers call the same global functions as before. In a real component, define them inside the component or pass them as props.
- Controlled inputs. If you need the value in state, replace
defaultValuewithvalue={email}and addonChange={e => setEmail(e.target.value)}. - Whitespace. JSX trims line breaks between tags. Where an inline space between elements matters, the converter inserts
{' '}so the rendered text matches the HTML. - TypeScript. The output is valid TSX as well; rename the file to
.tsxand add prop types if your component takes props.
Frequently asked questions
Why can't I paste HTML straight into JSX?
JSX looks like HTML but compiles to JavaScript, so a few rules differ: class and for are reserved words (use className and htmlFor), the style attribute takes an object, every tag must be closed (<br />), attribute names are camelCase (tabIndex, onClick) and a component can only return one root element, so siblings need a fragment <>…</>.
How are inline styles converted?
The style string is split into declarations and each property is camelCased: background-color becomes backgroundColor and vendor prefixes like -webkit-transition become WebkitTransition. Pure numbers stay numbers (zIndex: 10, opacity: 0.5); values with units stay strings ('12px'). CSS custom properties keep their name: '--gap': '8px'.
What happens to onclick and other inline event handlers?
They are renamed to React's camelCase events (onclick → onClick, ondblclick → onDoubleClick) and the code is wrapped in an arrow function, for example onClick={() => { save(); }}. If the code uses event, it becomes (event) => …. You can also choose to drop them. In React you would usually move that logic into a function in the component.
Why does value become defaultValue?
In React, an input with a value prop but no onChange handler is read-only, and React warns about it. defaultValue and defaultChecked set the initial value while letting the user type, which matches how the static HTML behaved. Turn the option off if you plan to add state and onChange yourself.
Does it work with SVG?
Yes. SVG attributes such as stroke-width, fill-rule, clip-path and stop-color are converted to camelCase, xlink:href becomes xlinkHref, and element names like linearGradient keep their case. Attributes React expects as-is, such as viewBox, are kept.
Is the HTML sent to a server?
No. The converter uses your browser's own HTML parser and runs entirely on your device. No scripts in your HTML are executed.