DevToolsmith

HTML to JSX Converter

Paste HTML to get valid JSX for React: className and htmlFor, style objects, closed tags, JSX comments and editable form fields. Wrap it in a component with typed props if you like.

Runs 100% in your browser — nothing is uploaded

HTML
Tip: drop a file here432 chars · 432 bytes · 7 lines
JSX
0 chars · 0 bytes · 0 lines

Example

HTML
<div class="field">
  <label for="q" style="font-weight: 600">Search</label>
  <input id="q" type="search" value="mugs" autofocus>
  <p>Press <kbd>Enter</kbd> to search.</p>
</div>
JSX
<div className="field">
  <label htmlFor="q" style={{ fontWeight: '600' }}>Search</label>
  <input id="q" type="search" defaultValue="mugs" autoFocus />
  <p>Press <kbd>Enter</kbd> to search.</p>
</div>

What changes between HTML and JSX

HTMLJSXWhy
class="btn" className="btn" class is a reserved word in JavaScript.
for="email" htmlFor="email" Same reason: for is a keyword.
style="margin-top: 4px" style={{ marginTop: '4px' }} Styles are objects with camelCase properties.
<br>, <img …> <br />, <img … /> Every tag must be closed.
tabindex, maxlength, colspan tabIndex, maxLength, colSpan Multi-word attributes are camelCase.
<!-- note --> {/* note */} HTML comments aren’t valid JSX.
onclick="save()" onClick={save} Handlers are functions, not strings (the converter removes them).
value="x" on an input defaultValue="x" value without onChange makes the field read-only in React.
data-id, aria-label data-id, aria-label Unchanged: data-* and aria-* stay hyphenated.

After converting

  • Replace repeated markup with .map() over your data, and give each item a key.
  • Move removed onclick code into functions and attach them with onClick.
  • Turn <a href> links between your own pages into your router’s link component, such as <Link to> or Next.js <Link href>.

Converting icons? The SVG to JSX page is set up for SVG files, with props spread onto the <svg>. To tidy the HTML first, run it through the HTML Formatter.

Frequently asked questions

How do I convert HTML to JSX?

Paste the HTML into the converter above. It renames attributes to their React names (class to className, for to htmlFor, tabindex to tabIndex), turns inline styles into style objects, closes void tags like <br /> and <img />, converts comments, and keeps the spaces between text and tags that JSX would otherwise drop.

Why does the output use defaultValue instead of value?

In React, an input with a value prop and no onChange handler is read-only, and React logs a warning. defaultValue and defaultChecked set the starting value and leave the field editable. Untick “defaultValue for fields” if you are going to add state and onChange yourself.

What happens to onclick and other inline event handlers?

They are removed and listed in a warning. JSX event handlers are functions, such as onClick={handleClick}, not strings of code, so the original code has to be moved into your component by hand.

Why are there {" "} pieces in the output?

JSX removes whitespace at the start and end of each line. When text and a tag are on different lines but must be separated by a space, the space is written out as {" "} so the rendered text stays the same as the HTML.

Does it work for Preact, Solid, Qwik and other JSX frameworks?

Yes. Tick “Keep class” for Preact and Solid, which accept class and for directly. Everything else, such as self-closing tags, style objects and comments, is the same in every JSX dialect.