Skip to content
AZ Tools

HTML → JSX Converter

Paste an HTML snippet and get React-ready JSX — class becomes className, onclick becomes onClick, and void tags self-close.

JSX
<>
  <div className="container">
    <label htmlFor="email">Email</label>
    <input type="email" id="email" required />
    <button onClick="submit()" tabIndex="0" style={{ color: '#fff', backgroundColor: 'rebeccapurple', fontSize: '14px' }}>
      Send
    </button>
    {/* footer */}
    <p className="muted">By signing up you agree to our <a href="/terms">terms</a>.</p>
  </div>
</>

Quoted string attribute values stay as strings; if you need a JS expression instead, change it in the JSX after copying.

How to use

  1. Paste an HTML snippet.
  2. Toggle the wrap-in-fragment option if you want a single root for a React component.
  3. Copy the JSX into your component file.

About this tool

Show

Hand-rolled converter that rewrites the boring chores of porting HTML to a React component: attribute renames (class, for, tabindex, etc.), inline event-handler capitalization (onclick → onClick), self-closing of void tags (<br> → <br />), HTML comments to JSX comments, and optional conversion of style="color: red; font-size: 14px" to a style={{ color: 'red', fontSize: '14px' }} object literal.

Those five rewrites cover most of what a paste needs, and the void-tag one is what makes the difference between output that compiles and output that does not. JSX requires every element to be closed, so an unclosed <img> or <input> is a syntax error rather than something the parser repairs the way a browser would. Comments matter for the same reason: <!-- … --> is not valid inside JSX and has to become {/* … */}.

The style conversion changes a string into an object, which means the values become JavaScript and a few things stop working. CSS custom properties keep their dashed names and have to stay quoted, !important cannot be expressed in the object form at all, and a unitless number in the object is treated as pixels for most properties but not for line-height or z-index. If a declaration is doing something unusual, leaving the inline style as a class is usually cleaner than converting it.

What the converter does not do is turn markup into a component. It rewrites syntax, so an onclick attribute becomes onClick but its value stays a string rather than a function reference, and anything that depended on the surrounding page — a script, a form's default submission, an id referenced from elsewhere — still needs a decision from you. Server-rendered templating syntax left in the HTML passes through as literal text.

The parsing is textual rather than a full HTML parse, so deeply malformed input can confuse it. Check the output compiles before trusting a large paste.

Frequently asked questions

What attributes get renamed?

All the ones React renames: class / for / tabindex / readonly / maxlength / contenteditable / spellcheck / autocomplete / autofocus / enctype / crossorigin / srcset / rowspan / colspan / usemap / datetime, plus every on… event handler. aria- and data- attributes stay kebab-case.

What if my inline style has CSS variables?

Properties starting with -- are quoted as string keys ('--accent': 'blue') so they survive into the JSX. Vendor-prefixed properties like -webkit-… are also quoted.

Does it run my JavaScript or eval scripts?

No. The parser is a small hand-written scanner — <script> tags pass through as text just like any other element. The conversion is purely string-level.

Why does my converted markup render differently from the HTML?

Two rules bite most often. Whitespace between elements is significant in HTML but collapsed away by JSX in places you may be relying on, so inline elements can end up glued together. And a browser silently repairs invalid nesting — a stray table row, a div inside a paragraph — while JSX preserves exactly what you wrote, so structure the browser was quietly fixing now stays broken.

Is it safe to paste HTML I did not write?

Converting it is safe here, because nothing runs — the text is transformed, not executed. Rendering the result is the part that deserves care: attributes and inline handlers become real code once mounted in your app. Read what came out before shipping it, and never route untrusted markup through a raw HTML injection to avoid the conversion.

Related tools