What Is HTML to JSX Conversion?
HTML to JSX conversion is the process of transforming standard HTML markup into JSX syntax that React components can render. JSX looks similar to HTML but follows JavaScript naming conventions and rules. Attributes like class become className, for becomes htmlFor, and inline style strings are replaced with JavaScript objects. These changes are required because JSX compiles to React.createElement() calls, where attribute names must match the DOM API property names rather than HTML attribute names.
The mapping between HTML attributes and JSX props is defined by React's DOM elements documentation. React uses camelCase for multi-word attributes (tabindex becomes tabIndex, maxlength becomes maxLength) because JavaScript identifiers cannot contain hyphens. Self-closing tags like <img>, <br>, and <input> must include a trailing slash in JSX (<img />) since JSX follows XML rules where every tag must be explicitly closed.
Beyond attribute renaming, HTML to JSX conversion also handles inline styles and comments. HTML style attributes use CSS syntax as a string (style="color: red; font-size: 14px"), while JSX expects a JavaScript object with camelCase property names (style={{ color: 'red', fontSize: '14px' }}). HTML comments (<!-- -->) become JSX expression comments ({/* */}). Missing any of these transformations produces runtime errors or silent rendering bugs in React applications.
Why Use an HTML to JSX Converter?
Manually renaming attributes and rewriting style strings across dozens of HTML elements is slow and error-prone. A converter handles every transformation at once, letting you paste HTML from any source and get valid JSX in seconds.
HTML to JSX Use Cases
HTML to JSX Attribute Mapping Reference
The table below lists the HTML attributes that change when converted to JSX. Attributes not listed here (id, src, href, alt, placeholder, etc.) remain unchanged because their HTML names already match the corresponding DOM API property names.
| HTML Attribute | JSX Prop | Notes |
|---|---|---|
| class | className | Reserved word in JavaScript |
| for | htmlFor | Reserved word in JavaScript |
| tabindex | tabIndex | camelCase convention |
| readonly | readOnly | camelCase convention |
| maxlength | maxLength | camelCase convention |
| minlength | minLength | camelCase convention |
| cellpadding | cellPadding | camelCase convention |
| cellspacing | cellSpacing | camelCase convention |
| rowspan | rowSpan | camelCase convention |
| colspan | colSpan | camelCase convention |
| enctype | encType | camelCase convention |
| autocomplete | autoComplete | camelCase convention |
| autofocus | autoFocus | camelCase convention |
| autoplay | autoPlay | camelCase convention |
| contenteditable | contentEditable | camelCase convention |
| crossorigin | crossOrigin | camelCase convention |
| novalidate | noValidate | camelCase convention |
| allowfullscreen | allowFullScreen | camelCase convention |
| spellcheck | spellCheck | camelCase convention |
| http-equiv | httpEquiv | Hyphen removed, camelCase |
| onclick | onClick | Event handler camelCase |
| onchange | onChange | Event handler camelCase |
| onsubmit | onSubmit | Event handler camelCase |
Inline Style Conversion: HTML vs JSX
Inline styles are the most error-prone part of HTML to JSX conversion because both the value format and the property names change:
<div style="background-color: #fff; font-size: 14px; margin-top: 10px;">
<div style={{
backgroundColor: '#fff',
fontSize: '14px',
marginTop: 10
}}>Code Examples
These examples show how to convert HTML to JSX programmatically in different languages and environments. Each covers attribute renaming, style conversion, and self-closing tag handling.
// Simple attribute conversion using string replacement
function htmlToJsx(html) {
return html
.replace(/\bclass=/g, 'className=')
.replace(/\bfor=/g, 'htmlFor=')
.replace(/\btabindex=/g, 'tabIndex=')
.replace(/<!--([\s\S]*?)-->/g, '{/*$1*/}')
}
htmlToJsx('<div class="box" tabindex="0"><!-- note --></div>')
// → '<div className="box" tabIndex="0">{/* note */}</div>'import parse from 'html-react-parser'
// Parse HTML string into React elements (handles all JSX rules)
const element = parse('<div class="card"><img src="photo.jpg" alt="Photo"></div>')
// Returns: React.createElement('div', { className: 'card' },
// React.createElement('img', { src: 'photo.jpg', alt: 'Photo' }))
// With custom element replacement
const options = {
replace(domNode) {
if (domNode.name === 'img') {
return <OptimizedImage src={domNode.attribs.src} alt={domNode.attribs.alt} />
}
}
}
const custom = parse('<img src="photo.jpg" alt="Photo">', options)from bs4 import BeautifulSoup
import re
ATTR_MAP = {
'class': 'className', 'for': 'htmlFor',
'tabindex': 'tabIndex', 'readonly': 'readOnly',
'maxlength': 'maxLength', 'autocomplete': 'autoComplete',
}
def html_to_jsx(html: str) -> str:
"""Convert HTML attribute names to JSX equivalents."""
for html_attr, jsx_attr in ATTR_MAP.items():
html = re.sub(rf'\b{html_attr}=', f'{jsx_attr}=', html)
# Convert HTML comments to JSX comments
html = re.sub(r'<!--(.*?)-->', r'{/*\1*/}', html)
return html
print(html_to_jsx('<label for="email" class="field">Email</label>'))
# → '<label htmlFor="email" className="field">Email</label>'package main
import (
"fmt"
"strings"
)
var attrMap = map[string]string{
"class=": "className=",
"for=": "htmlFor=",
"tabindex=": "tabIndex=",
"readonly": "readOnly",
}
func htmlToJSX(html string) string {
result := html
for old, new := range attrMap {
result = strings.ReplaceAll(result, old, new)
}
// Convert comments
result = strings.ReplaceAll(result, "<!--", "{/*")
result = strings.ReplaceAll(result, "-->", "*/}")
return result
}
func main() {
html := `<div class="wrapper"><input readonly tabindex="1"></div>`
fmt.Println(htmlToJSX(html))
// → <div className="wrapper"><input readOnly tabIndex="1"></div>
}