SVG to JSX

Paste SVG and get JSX you can drop straight into a React component. Attributes are renamed to their JSX form (stroke-widthstrokeWidth, classclassName), inline style strings become style objects, comments are converted to JSX comments, and every tag is properly closed. Optionally wrap the result in a function or arrow component that spreads props onto the root. Converted entirely in your browser.

JSX output

How to use the SVG to JSX

Paste an <svg> element — an exported icon, a logo, an illustration — and the JSX appears instantly. Choose how to wrap it: a named function component, a shorter arrow component, or just the raw JSX with no wrapper if you're pasting into existing markup. Set the component name and, if you want the icon to accept styling and event props, leave spread props on so {...props} lands on the root <svg>. Then copy the result.

The conversion handles the things that make React reject raw SVG: hyphenated and namespaced attributes are camelCased (stroke-linecapstrokeLinecap, xlink:hrefxlinkHref), class becomes className, style="…" strings are parsed into the object literal React expects, and HTML comments become {/* … */}. data-* and aria-* attributes keep their hyphens, as React requires. Because it parses the SVG with the browser's own XML parser rather than guessing with regexes, nested groups and self-closing tags come out correctly.

Why raw SVG is not valid JSX

SVG and JSX look similar — both are angle-bracket markup — but JSX is JavaScript, and it follows the DOM's property names rather than HTML's attribute names. In the DOM, the class attribute is exposed as the className property, and hyphenated SVG presentation attributes like stroke-width are camelCased to strokeWidth. React's JSX mirrors those property names, so pasting raw SVG straight into a component produces warnings or outright errors. The style attribute is the sharpest edge: in HTML it's a string, but in JSX it must be an object with camelCased keys, so style="fill:red" has to become style={{ fill: "red" }}.

There are a handful of other adjustments. Namespaced attributes such as xlink:href and xml:space map to specific JSX names (xlinkHref, xmlSpace). HTML comments aren't valid inside JSX and must be rewritten as {/* … */} expressions. Every element has to be explicitly closed, since JSX has no void elements. And data-* and aria-* attributes are the exception to the camelCasing rule — React passes them through with their hyphens intact, so they must be left alone. Getting any of these wrong is the difference between a component that renders and one that throws.

Doing this by hand for a single small icon is tedious; doing it for a sheet of them is error-prone. Converting the SVG to a component also unlocks what makes inline SVG worthwhile in React: because the markup is now JSX, you can drive fill and stroke from currentColor, size it with props, and forward className and event handlers by spreading props onto the root. The result is a reusable, themeable icon component rather than a static image — which is why icon libraries ship their glyphs as generated components built by exactly this kind of transform.

Common use cases

  • Icon components. Turn an exported SVG icon into a reusable, prop-driven React component.
  • Design handoff. Drop a designer's SVG into a codebase without hand-fixing every attribute.
  • Theming. Convert so fill and stroke can use currentColor and respond to CSS.
  • Inline illustrations. Embed an SVG directly in JSX instead of loading it as an image.

Frequently asked questions

What does it change about the SVG?

It camelCases hyphenated and namespaced attributes (stroke-width to strokeWidth, xlink:href to xlinkHref), turns class into className, converts inline style strings into JSX style objects, rewrites HTML comments as JSX comments, and closes every tag. data-* and aria-* attributes keep their hyphens, as React requires.

Can it produce a full component?

Yes. Choose a function component or an arrow component and give it a name, and the JSX is wrapped with an export. You can also pick JSX-only output if you just want the markup to paste into existing code.

What does spreading props do?

With it on, {...props} is added to the root , so the component forwards className, style, width, onClick, and any other props you pass. That is what lets a generated icon be sized, coloured, and handled by its parent.

Does it work for any SVG?

It parses the SVG with the browser's XML parser, so nested groups, gradients, paths, and self-closing tags convert correctly. If the input is not a well-formed element it reports a parse error rather than emitting broken JSX.

Is my SVG uploaded?

No. Parsing and conversion happen entirely in your browser with client-side JavaScript, so nothing you paste leaves your machine.
Embed this tool on your site

Free to embed, no attribution required (but appreciated). Paste this where you want the tool to appear: