To convert HTML to JSX, paste it below and the converter does the three jobs a copy-paste into React always needs: renames the forbidden attributes (classclassName, forhtmlFor, tabindextabIndex), turns style strings into objects (style="color:red"style={{color: 'red'}}), and self-closes void tags. In the SVG tab it also renames hyphenated attributes to React's camelCase (stroke-widthstrokeWidth) and can wrap the result as a named component with a props spread — svgr-style output, no build step. Everything runs locally with the open-source react-magic engine.

Converter

HTML input
JSX output

Converted live as you type. The SVG tab applies React's attribute renames after conversion.
Advertisement

Attributes JSX Renames (Converter Handles All)

HTML / SVGJSXWhy
classclassNameDOM property name, not attribute
forhtmlForfor is a JS reserved word
tabindextabIndexcamelCase DOM property
readonlyreadOnlycamelCase DOM property
maxlengthmaxLengthcamelCase DOM property
autocompleteautoCompletecamelCase DOM property
colspan / rowspancolSpan / rowSpancamelCase DOM property
srcsetsrcSetcamelCase DOM property
value (input)defaultValueuncontrolled input default
stroke-widthstrokeWidthReact SVG attributes are camelCase
stroke-linecapstrokeLinecapsame
stroke-dasharraystrokeDasharraysame
fill-rule / clip-pathfillRule / clipPathsame
font-size / text-anchorfontSize / textAnchorsame
xlink:hrefxlinkHrefnamespaced attrs camelCase in React
xmlns:xlinkxmlnsXlinksame
aria-*, data-*unchangedReact expects the hyphens

Boolean attributes come through bare (disabled), numeric strings become expressions (width={24}), and viewBox stays exactly as it is — already valid camelCase.

How the HTML to JSX Converter Works

This page runs htmltojsx — the BSD-licensed converter from React's react-magic project, the engine behind React's own HTML→JSX playground — directly in your browser. It parses your markup into a real DOM tree, walks it, and re-serializes each node as JSX: attributes renamed to React's names, style strings converted to object literals, void elements self-closed, and text escaped where JSX needs it. The SVG tab layers a normalizer on top that renames hyphenated SVG attributes to React's camelCase forms (the same mapping the svgr toolchain applies) and can wrap the output as a named, exported component with a props spread on the root element.

A worked example: HTML

Input:

<div class="hero" id="top"><h1 style="color:red">Hello</h1><p>Text &amp; more <br/></p><input type="text" value="a" disabled><img src="x.png" alt="pic"></div>

Output (JSX mode):

<div className="hero" id="top"><h1 style={{color: 'red'}}>Hello</h1><p>Text &amp; more <br /></p><input type="text" defaultValue="a" disabled /><img src="x.png" alt="pic" /></div>

Four conversions happened: class became className, the style string became a style object, the input's value became defaultValue (the uncontrolled-input form React expects in plain markup), and <br>, <input>, <img> self-closed — JSX requires it.

A worked example: SVG

Input (a typical icon, with the attributes icon sets actually use):

<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon"><polyline points="3 17 9 11 13 15 21 7"></polyline></svg>

Output (component mode, named ActivityIcon, props spread on):

export default function ActivityIcon(props) { return ( <svg xmlns="http://www.w3.org/2000/svg" width={24} height={24} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" className="icon" {...props}> <polyline points="3 17 9 11 13 15 21 7" /> </svg> ); }

Paste the same SVG into React without conversion and the console fills with "Invalid DOM property" warnings while the stroke silently disappears — which is how most people find this tool.

What conversion can't do

Frequently Asked Questions

Why does class become className in JSX?

Because className is a property of the DOM API, not an HTML attribute name. React sets real DOM properties (element.className), and it does this at runtime, so JSX attribute names follow the property names: className, htmlFor, tabIndex. The converter renames all of them automatically.

What happens to inline styles?

HTML style strings become JavaScript objects. style="color:red" turns into style={{color: 'red'}}, and hyphenated CSS properties camel-case themselves: font-size becomes fontSize. The converter produces the object literal for you, quoted values included.

Why does React warn about stroke-width in SVG?

The message reads 'Invalid DOM property stroke-width. Did you mean strokeWidth?' React's SVG attributes are camelCase like its HTML ones, so stroke-width, stroke-linecap, clip-path, and fill-rule must become strokeWidth, strokeLinecap, clipPath, and fillRule. The SVG tab here renames them after converting — aria-* and data-* keep their hyphens, since React expects those verbatim.

Can this convert SVG into a React component?

Yes — the SVG tab does the conversion plus the wrapping that icon workflows expect: name the component, spread props onto the root element (svgr-style, so callers can set size and color), and export it as a default function component, optionally in TypeScript. That reproduces the output of the svgr toolchain without a build step.

Is my HTML sent to a server?

No. The converter runs on the open-source htmltojsx engine (BSD-licensed, from React's react-magic project) directly in your browser tab. Paste in proprietary markup if you like — the network tab shows no requests after the engine loads.

What can't HTML to JSX conversion handle?

JavaScript and CSS in script and style tags doesn't translate — JSX treats their contents as text, and React wants real event handlers (onclick becomes onClick as a function prop, which no static converter can invent). Web components, server-side includes, and template syntax (mustaches, ERB) come through literally. Convert markup, then wire behavior by hand.

Advertisement