Quick answer
To convert SVG to JSX, rename attributes to their React names (class becomes className, stroke-width becomes strokeWidth, xlink:href becomes xlinkHref), turn style strings into objects, and wrap the markup in a component that spreads props onto the root svg. Playxoft's free SVG to JSX Converter does all of that in the browser, strips scripts and editor metadata, optimizes paths and outputs TypeScript, JavaScript or React Native components.
- React and React Native
- TypeScript or JavaScript
- currentColor and size props
- Script and handler removal
- Path optimizer
- Multi-file batch
- Before and after preview
How to use the SVG to JSX Converter
- 1Paste SVG markup into SVG input, drop one or more .svg files on it, or click Load example.
- 2Choose TypeScript or JavaScript, and a Named export or Default export.
- 3Set Size and Accessibility, and switch on currentColor, forwardRef or memo if your icon system uses them.
- 4Pick the React, React Native or SVG tab, and compare Original with Result in the preview to confirm nothing changed visually.
- 5Copy or download the component. With several files, use Copy all or download every component as one module.
Why do SVG attributes change in JSX?
JSX looks like markup but compiles to JavaScript function calls, and each attribute becomes a property on a props object. That is why a few SVG attributes must be renamed before React accepts them:
| In SVG | In JSX | Why |
|---|---|---|
class="icon" | className="icon" | class is a reserved word in JavaScript |
stroke-width="2" | strokeWidth="2" | React names multi-word props in camelCase |
fill-rule="evenodd" | fillRule="evenodd" | The same rule covers every hyphenated presentation attribute |
xlink:href="#a" | xlinkHref="#a" | JSX compilers reject namespaced names by default |
xml:space="preserve" | xmlSpace="preserve" | Same namespace rule |
style="fill:red;stroke-width:2" | style={{ fill: "red", strokeWidth: "2" }} | React styles are objects with camelCase keys |
aria-hidden, data-id | unchanged | React passes aria-* and data-* through as written |
viewBox, gradientUnits | unchanged | These are already camelCase in SVG |
Pasting raw SVG into a component usually "works" until it hits one of these: React logs an invalid DOM property warning for stroke-width, and Babel or SWC stop with a namespace error on xlink:href. Note that xlink:href is legacy SVG 1.1 syntax; plain href works in every current browser.
Inline SVG, img or sprite: which should I use?
How you ship an icon matters more than how small its file is:
| Method | Color with CSS | Cached as a file | Adds to your JS bundle | Best for |
|---|---|---|---|---|
| Inline component (this tool) | Yes, via currentColor | No | Yes | Icons that change color, size or animate |
<img src="icon.svg"> | No | Yes | No | Logos and illustrations |
Sprite: <use href="/sprite.svg#icon"> | Yes, via currentColor | Yes | No | Large icon sets reused across many pages |
CSS mask-image | Yes, through background-color | Yes | No | Decorative icons in CSS |
Inline components are the most flexible: props, hover states, dark mode and accessibility all just work. The trade-off is that every icon's path data lives in your JavaScript and in every server-rendered page that uses it. For a few dozen icons that is negligible; for hundreds, a sprite sheet referenced with <use> keeps HTML and bundles small. External <use> references must be same-origin.
What does SVG optimization remove, and what is safe?
Design tools export far more than the drawing. A typical Illustrator or Inkscape file carries an XML prolog, generator comments, <metadata>, sodipodi:namedview, layer ids like Layer_1 and coordinates with four decimals. None of it affects rendering, and this converter removes it every time.
The optional optimizer goes further, and only does what cannot change the picture:
- Rounds numbers. In a 24-unit viewBox, two or three decimals are far below one rendered pixel, so
M12.0001,2.2500becomesM12 2.25. - Compacts path data with a real path parser, so arc flags and run-together numbers like
1.5.5(1.5, then .5) survive. - Drops empty groups and defs, and unwraps groups that have no attributes.
- Removes default values such as
stroke-miterlimit="4", but only where no ancestor sets a different value, and never inside<defs>or<symbol>, whose content inherits from where it is used.
What is not safe: rounding a tiny viewBox (such as 0 0 1 1) to two decimals, deleting ids that CSS or scripts target, and deleting the viewBox, which stops an icon from scaling. Some older optimizer presets removed the viewBox by default, so check yours. For build pipelines, SVGO is the standard optimizer and SVGR (via @svgr/webpack or vite-plugin-svgr) turns imported .svg files into React components at build time; this page is for one-off conversions and quick checks.
How do I make an SVG icon accessible?
It depends on what the icon does. Most icons sit next to visible text and are decorative, so hide them from screen readers:
<button>
<TrashIcon aria-hidden="true" />
Delete
</button>An icon that carries meaning on its own, such as a status badge, needs an accessible name. Give the svg role="img" and either an aria-label or a <title> referenced with aria-labelledby. The Title prop option generates exactly that, with an id from React's useId so several icons on a page never share one:
<WarningIcon title="Payment failed" />For icon-only buttons, put the label on the button (aria-label="Delete") and keep the icon hidden. The rule behind all of this is WCAG 1.1.1 Non-text Content.
How is a React Native SVG component different?
React Native has no DOM, so SVG comes from the react-native-svg library, whose elements are imported components: Svg, Path, G, Circle, LinearGradient and so on. The React Native tab handles the differences for you:
- Element names are capitalized and imported from
react-native-svg. - There is no CSS, so
<style>blocks andclassNamedo nothing. Styles must become props (fill,strokeWidth), which is why Inline styles matters here. - Sizes are numbers in density-independent pixels;
1emdoes not exist, so it becomes a number. currentColorworks and resolves to thecolorprop onSvg.- Filter support in react-native-svg is recent and covers only some primitives, so check the library's docs before relying on one.
If you import many .svg files directly, react-native-svg-transformer lets Metro do this conversion at build time.
Frequently asked questions
Last updated by the Playxoft engineering team.