HTML
TSX
Need AI-powered conversion? Try Lora →

How to convert HTML to TSX

  1. Paste your HTML markup into the input field — a component template, a design export, or a snippet from an existing page.
  2. Click "Convert" — the TSX output appears instantly: attributes renamed, styles converted, and the JSX wrapped in a typed React.FC component scaffold.
  3. Switch to "TSX → HTML" using the toggle above if you need the reverse direction.
  4. Click "Copy" to copy the TSX and paste it directly into your TypeScript React project.
  5. Rename Component and fill in the Props interface to match your actual prop types.

How the HTML to TSX converter works

The converter applies the same attribute transformations as HTML → JSX — class → className, for → htmlFor, tabindex → tabIndex, camelCase events, inline style string → object — and then wraps the resulting JSX in a complete TypeScript React component scaffold: an import statement, an empty Props interface, a React.FC<Props> arrow function, and an export default. The entire conversion runs in your browser — no data is sent to any server.

TSX is JSX written in a TypeScript file. The structural transformation rules are identical to JSX, but the output is typed from the start: you get a React.FC<Props> component declaration with an interface Props {} placeholder ready for your prop definitions. This saves the first few minutes of every "paste from Figma" workflow.

HTML input → TSX component output
// Input HTML:
<div class="card">
  <label for="name">Name</label>
  <input type="text" id="name" readonly tabindex="1"
         style="color: blue; font-size: 14px">
  <button onclick="handleSubmit()">Submit</button>
</div>

// Output TSX:
import React from 'react'

interface Props {}

const Component: React.FC<Props> = () => {
  return (
    <div className="card">
      <label htmlFor="name">Name</label>
      <input type="text" id="name" readOnly tabIndex={1}
             style={{ color: 'blue', fontSize: '14px' }} />
      <button onClick={handleSubmit}>Submit</button>
    </div>
  )
}

export default Component

HTML attributes that change in TSX (same as JSX)

TSX uses the same attribute names as JSX — the TypeScript layer adds types but does not change attribute naming. Every HTML attribute that differs in JSX also differs in TSX. The full mapping is identical to the HTML → JSX conversion.

HTMLTSX (= JSX)Reason
class="…"className="…"class is a JS reserved word
for="…"htmlFor="…"for is a JS reserved word
onclick="fn()"onClick={fn}camelCase event; pass function reference
tabindex="1"tabIndex={1}camelCase; numeric value as JS expression
readonlyreadOnlycamelCase boolean attribute
maxlength="10"maxLength={10}camelCase; numeric value
style="color:red"style={{ color: 'red' }}CSS string → JS object
font-size: 14pxfontSize: '14px'kebab-case → camelCase CSS property
<br><br />void elements must self-close
<!-- text -->{/* text */}HTML comments → JSX comments

The TypeScript component scaffold explained

The converter wraps every output in a minimal but complete TypeScript React component. Each part of the scaffold has a purpose.

TSX scaffold breakdown
import React from 'react'   // Required for JSX transform in older setups;
                               // React 17+ with new JSX transform: can be removed

interface Props {}             // Replace with your actual prop definitions:
                               // interface Props { title: string; count?: number }

const Component: React.FC<Props> = () => {  // Rename Component to match your file name;
                                             // add destructured props: ({ title, count })
  return (
    // Your converted JSX here
  )
}

export default Component       // Rename to match the component name above

After conversion, the typical next steps are: rename Component to match your file name, add prop definitions to the Props interface, destructure the props in the function signature, and replace any static values that should come from props with the corresponding prop references.

TSX vs JSX — what actually differs

JSX and TSX are identical at the markup level. The differences are in what TypeScript adds on top:

  • Type-checked props — TypeScript validates that every prop passed to a component matches its declared type at compile time. JSX has no equivalent check.
  • React.FC<Props> declaration — the function type annotation gives TypeScript enough information to check prop usage inside the component and at every call site.
  • Generic components — TSX supports typed generics: function List<T extends { id: string }>({ items }: { items: T[] }). JSX has no syntax for this.
  • Event handler types — TSX event handlers are typed: (e: React.ChangeEvent<HTMLInputElement>) => void. JSX accepts any function without type checking.
  • Build output — both JSX and TSX compile to identical JavaScript. TypeScript types are erased at build time and have zero runtime cost.

Inline styles: the same conversion, type-checked

Inline style conversion works identically to HTML → JSX. The CSS string is split by semicolons, each property name is camelCased, and the result is written as a JavaScript object literal. In TSX, the resulting object is type-checked against React.CSSProperties — TypeScript will catch misspelled property names at compile time.

Inline style conversion in TSX
// Input HTML style string:
style="background-color: #fff; font-size: 16px; margin-top: 8px; z-index: 10"

// Output TSX style object (type: React.CSSProperties):
style={{ backgroundColor: '#fff', fontSize: '16px', marginTop: '8px', zIndex: 10 }}

// TypeScript catches misspellings at compile time:
// style={{ backroundColor: '#fff' }}  → Error: unknown property

Frequently Asked Questions

What is the difference between JSX and TSX?
JSX is React's HTML-like syntax extension for JavaScript (.jsx files). TSX is the same syntax used in TypeScript files (.tsx files). The markup is identical — the only difference is that TSX files are processed by the TypeScript compiler, which type-checks props, event handlers, and component interfaces. Converting HTML to TSX gives you the JSX markup plus a typed component wrapper from the start.
Does the converter add TypeScript types to the converted JSX?
The converter adds a minimal typed scaffold: an interface Props {} placeholder and a React.FC<Props> type annotation on the component function. It does not infer prop types from the HTML content — the Props interface is intentionally empty so you can fill in your actual prop definitions. TypeScript types for existing attributes come from the React type definitions already installed in your project.
Why is the component named "Component" in the output?
The converter has no way to know what your component should be called — it only sees the HTML markup. "Component" is a safe placeholder that TypeScript accepts. After conversion, rename it to match your file name. In TypeScript, the export default name and the file name should match for best IDE support.
Do I need to import React in TSX files?
With React 17+ and the new JSX transform (configured in tsconfig.json with "jsx": "react-jsx"), you no longer need to import React at the top of every file. The converter includes the import for compatibility with older setups. If your project uses the new transform, you can safely remove the import React line from the output.
Why does class become className in TSX?
For the same reason as in JSX: class is a reserved keyword in JavaScript. Since TSX compiles to TypeScript and then to JavaScript, using class as an attribute name would create a syntax conflict. React uses className, which maps directly to the DOM's className property.
How are void elements handled in TSX?
Void elements (br, hr, img, input, meta, link) must self-close in JSX and TSX — <br> becomes <br />, <img src="…"> becomes <img src="…" />. This is a JSX requirement that the TypeScript compiler also enforces in TSX files. The converter applies self-closing automatically to all void elements.
What happens to event handlers like onclick="handleSubmit()"?
Event attribute names are converted to camelCase (onclick → onClick, onchange → onChange, onmouseenter → onMouseEnter). After conversion, the string value should be replaced with a proper function reference: onClick={"handleSubmit()"} → onClick={handleSubmit}. The function must be in scope in your component.
Can I convert a full HTML page to a TSX component?
You can convert a section of the page, but a full document including html, head, and body tags does not map to a valid React component. Extract the meaningful content section, convert it to TSX, then fill in the Props interface and event handlers.
What about SVG attributes like viewBox and stroke-width?
The converter handles SVG attribute renaming. stroke-width becomes strokeWidth, fill-opacity becomes fillOpacity. Native SVG camelCase attributes like viewBox, gradientUnits, and preserveAspectRatio are left unchanged — they are already in the correct form for JSX and TSX.
Does the output TypeScript compile without errors?
The scaffold compiles cleanly with an empty Props interface. You will get TypeScript errors only when you add prop references that are not declared in the interface. The interface Props {} placeholder is valid TypeScript that produces no errors on its own.
Is any data sent to a server during conversion?
No. The entire conversion runs in your browser using JavaScript string processing. No data is transmitted over the network — there are no file size limits, no rate limits, and no privacy concerns.
What is React.FC and should I use it?
React.FC (React.FunctionComponent) is a TypeScript generic type for React functional components. It accepts a type parameter for the props: React.FC<Props>. Some teams prefer explicit prop types without React.FC — both approaches are valid. The converter uses React.FC as a widely recognized pattern that gives you type safety with minimal boilerplate.