SVG to JSX Converter

Convert SVG to a React JSX component instantly in your browser. Handles camelCase attributes, className, optional TypeScript, forwardRef, and memo wrapping. Free, no signup.

  • Runs in your browser
  • Your data never leaves your browser
  • Free · No Sign-Up
The default is MyIcon. Other than ASCII letters, digits, _ and $, characters are removed from the generated name. A leading lowercase ASCII letter becomes uppercase. Edits convert after 200 ms.
Add SVG prop types. Without forwardRef, the component uses React.FC; with forwardRef, its SVG element and props get generic types. This option converts immediately.
Wrap the component in forwardRef and add ref={ref} to the first svg element before spread props. This option converts immediately.
Wrap the default export in memo. This option converts immediately.
Copy the complete displayed component. Empty output is not copied.

Paste one SVG icon at a time. Input changes convert after 200 ms; only the first svg element receives spread props. Ctrl/⌘+L clears the text fields and status while focus is in this tool.
Read the generated component before using it. Styles that cannot be preserved clear the output and disable Copy; the status gives the position and reason.
Examples, details and FAQ Worked examples, how it compares with other tools, and answers to common questions.

Attribute Conversion Rules

SVGJSX
stroke-widthstrokeWidth
stroke-linecapstrokeLinecap
fill-rulefillRule
clip-pathclipPath
classclassName
font-sizefontSize
text-anchortextAnchor
xmlns="..."(removed)

Output Modes

  • Default: Plain function component with no TypeScript annotation.
  • TypeScript: Adds React.FC<React.SVGProps<SVGSVGElement>> type so props like className, style, and onClick work without extra declarations.
  • forwardRef: Wraps the component in React.forwardRef, exposing the SVG element ref to the parent.
  • memo: Wraps the final export in React.memo to skip unnecessary re-renders.

Common Use Cases

  • Converting Figma or Illustrator SVG exports into React icon components
  • Migrating an SVG icon library to a JSX-based design system
  • Making SVG icons accept className, style, and other React props
  • Building accessible icon components that accept an aria-label via spread props

Example

A 24 × 24 plus icon, component name PlusIcon, all options off:

<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path stroke="#000" stroke-width="2" stroke-linecap="round" d="M12 5v14M5 12h14"/></svg>

Output:

import React from 'react';

function PlusIcon(props) {
  return (
    <svg width="24" height="24" fill="none" viewBox="0 0 24 24" {...props}><path stroke="#000" strokeWidth="2" strokeLinecap="round" d="M12 5v14M5 12h14" /></svg>
  );
}

export default PlusIcon;

xmlns is gone, stroke-width and stroke-linecap are camelCase, and the markup is copied as written otherwise. {...props} comes after the root’s own attributes, the same place as svgr’s default (expandProps: 'end'), so props you pass win: <PlusIcon width={48} fill="red" /> renders 48 px and red, and height stays 24. Values stay strings (strokeWidth="2"); React accepts both strings and numbers here. With TypeScript, forwardRef and memo all on, the same icon becomes const PlusIcon = forwardRef<SVGSVGElement, React.SVGProps<SVGSVGElement>>(function PlusIcon(props, ref) { ... }) with ref={ref} {...props} after the <svg>’s own attributes and export default memo(PlusIcon);. In React 19 forwardRef is no longer necessary: a function component can take ref as a prop.

An Illustrator export with Internal CSS, an inline style and xlink:href, component name Icon:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><!-- Generator: Adobe Illustrator --><defs><style>.cls-1{fill:#e11d48;}</style></defs><path id="a" class="cls-1" style="stroke:#000;stroke-width:2" d="M12 5v14"/><use xlink:href="#a"/></svg>

Output:

import React from 'react';

function Icon(props) {
  return (
    <svg viewBox="0 0 24 24" {...props}>{/* Generator: Adobe Illustrator */}<defs><style>{".cls-1{fill:#e11d48;}"}</style></defs><path id="a" className="cls-1" style={{ "stroke": "#000", "strokeWidth": "2" }} d="M12 5v14" /><use xlinkHref="#a" /></svg>
  );
}

export default Icon;

The comment becomes {/* ... */}, which React does not render. The CSS inside <style> becomes one JavaScript string, so its braces are no longer read as JSX; entities in it are decoded and a <![CDATA[ ... ]]> wrapper is removed. The style attribute becomes an object whose values are copied as written, and xlink:href becomes xlinkHref. Compiled with esbuild 0.21.5 and rendered with the React 19.2.0 development build, it gives <svg viewBox="0 0 24 24"><defs><style>.cls-1{fill:#e11d48;}</style></defs><path id="a" class="cls-1" style="stroke:#000;stroke-width:2" d="M12 5v14"></path><use xlink:href="#a"></use></svg> with no console warning.

Before You Paste: Export Settings

  • Figma: select the layer, then Export → SVG. Leave “Include ‘id’ attribute” off unless you target elements by ID.
  • Illustrator: File → Export → Export As → SVG. Presentation Attributes under Styling gives the shortest component. Internal CSS and Inline Style produce a <style> block or style="..." strings (Adobe: SVG export options); the converter turns them into a CSS string and style objects, as in the example above. A <style> block applies to the whole page, so two icons that both use .cls-1 change each other’s colors.
  • The converter removes the <?xml ... ?> line and turns comments into JSX comments, so you do not need to delete <!-- Generator: ... --> first.

What You Still Change by Hand

Each row was checked by compiling the output with esbuild 0.21.5 and rendering it with React 19.2.0.

In the pasted SVGWhat the converter outputsResult in ReactChange to
style="fill:red !important", a property written twice, or a CSS comment in styleNo output: the conversion is refused, Copy is disabled and the status line gives the position in the style—Move the rule into the <style> block or a CSS file, or remove !important
<text>{count}</text><text>&#123;count&#125;</text>Shows the text {count}Write {count} yourself if you want a variable
Hard-coded fill or stroke colorsKept as isThe icon ignores the text colorfill="currentColor" / stroke="currentColor"
<style> with class names shared by other iconsA CSS stringThe rules apply to the whole pageRename the classes, or export with Presentation Attributes

Limits

  • Pattern matching, not an XML parser. Comments, <style> blocks and CDATA sections are read first, so a tag written inside <!-- ... --> is not converted. Quoted values may contain > and /. Unclosed tags are not repaired.
  • Values are copied as written. Only attribute names change: aria-label="class schedule" stays aria-label="class schedule". The exceptions are style, which becomes an object, and text, where {, }, < and > are written as &#123;, &#125;, &lt; and &gt; so React shows the same characters.
  • Styles a React object cannot keep are refused. !important, the same property twice (a CSS fallback), CSS comments, escaped property names and unclosed quotes or brackets in a style attribute stop the conversion; the output is cleared and Copy is disabled until the input changes.
  • One component per paste. Only the first <svg> gets {...props}; paste sprite sheets one icon at a time.
  • Component name: characters other than letters, digits, _ and $ are dropped and the first letter is capitalized (plus-icon → Plusicon).
  • data-* and aria-* attributes keep their hyphens, as React expects.

FAQ

What does an SVG to JSX converter do?

It transforms a raw SVG file into a reusable React component. Key changes include converting hyphenated attributes to camelCase (stroke-width → strokeWidth), renaming class to className, removing the xmlns declaration, and wrapping the SVG markup inside a function component.

Why are SVG attributes renamed in JSX?

JSX is compiled to JavaScript, and hyphenated property names are not valid as JS identifiers. React requires camelCase versions such as strokeWidth, fillRule, and clipPath instead of the SVG/HTML attribute names.

What does the TypeScript option do?

When enabled, the output uses React.FC<React.SVGProps<SVGSVGElement>> as the component type, giving you full TypeScript support including prop autocomplete for SVG attributes.

What is forwardRef used for?

forwardRef lets parent components attach a ref to the underlying SVG element. Useful when you need programmatic access to the DOM node, for example to measure it or trigger animations.

What does memo wrapping do?

React.memo wraps the component so it only re-renders when its props change. This is a performance optimization for icon components that receive the same props on most renders.

Is anything sent to a server?

No. The conversion runs in your browser using JavaScript. No SVG data is transmitted.