Why HTML needs converting to JSX
JSX looks like HTML, but it compiles to JavaScript function calls, so a handful of HTML habits break it. class is a reserved word in JavaScript, inline styles must be objects instead of strings, every element must be closed, and comments use a different syntax. Converting a large template by hand is tedious and error-prone; this HTML to JSX converter parses your markup with the browser's HTML parser and rewrites it correctly in one step.
Example
<div class="card" id="profile">
<!-- Profile card -->
<img src="/avatar.png" alt="Avatar" width="64">
<label for="bio">Bio</label>
<textarea id="bio" maxlength="200" readonly>Hello!</textarea>
<h2 style="color: #333; font-size: 20px; margin-top: 0">Ada</h2>
<button onclick="follow()">Follow</button>
</div>becomes:
<div className="card" id="profile">
{/* Profile card */}
<img src="/avatar.png" alt="Avatar" width="64" />
<label htmlFor="bio">Bio</label>
<textarea id="bio" maxLength="200" readOnly defaultValue={"Hello!"} />
<h2 style={{ color: '#333', fontSize: '20px', marginTop: 0 }}>Ada</h2>
<button onClick={(event) => { follow() }}>Follow</button>
</div>When the input has more than one top-level element, the output is wrapped in a fragment (<>…</>), because a component must return a single root.
What the converter changes
- Attribute names –
class→className,for→htmlFor, and dozens of others such astabindex→tabIndex,colspan→colSpan,srcset→srcSetand SVG'sviewbox→viewBox. Hyphenated SVG attributes likestroke-widthbecome camelCase;data-*andaria-*stay as they are. - Inline styles – the CSS string becomes an object with camelCase keys. Plain numbers stay numbers, everything else becomes a string, and CSS custom properties keep their
'--name'keys. - Void elements –
<img>,<br>,<input>and friends are self-closed. - Form defaults –
valueandcheckedon inputs becomedefaultValueanddefaultChecked, which keeps the fields uncontrolled so React does not warn about a missingonChange. - Event handlers –
onclickbecomesonClickwith the original code wrapped in an arrow function. - Text – curly braces in text are escaped as
{'{'}, and whitespace between inline elements is preserved with{" "}. - Scripts and styles – contents of
<style>and<script>become template literals so special characters survive.
Options
- Component wrapper – wraps the JSX in
export default function MyComponent() { return (…); }. The name must start with an uppercase letter, as React requires for components. - Indentation – two spaces, four spaces or tabs to match your code style.
After converting
The output is a faithful, static translation. You will usually want to replace inline onclick code with real handler functions, move repeated markup into .map() loops and lift inline styles into CSS modules or your styling library. Run the result through the React formatter if you want Prettier-style formatting.
Going the other way, or working with other template languages? Try HTML to Pug, or tidy the original markup first with the HTML formatter.
Privacy
Parsing and conversion run in your browser. Your markup is not uploaded, which makes the tool safe for code from private projects.