SVG to JSX Converter

Free tool No sign-up
SVG Input
Preview
On light and dark — verify your colors survive both.
281B in → 448B out(+59%)
import { forwardRef } from 'react';

export const Icon = forwardRef(
  function Icon({ size = 24, ...rest }, ref) {
    return (
      <svg ref={ref} width={size} height={size} viewBox="0 0 48 48" fill="none" {...rest}>
            <rect x="4" y="4" width="40" height="40" rx="8" fill="#7C6CFF" />
            <path d="M16 24L22 30L34 18" stroke="white" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" />
          </svg>
    );
  }
);
Detected colors · 2
Detected issues
No issues found. Clean conversion.

About this tool

Paste any SVG and get a clean React component — attribute renames, color-to-prop swaps, forwardRef wrap with TypeScript and a size prop, and a live preview on light and dark backgrounds. Built for converting Figma exports, icon-library SVGs, and inline marketing graphics into shippable component code.

?

Why use this converter?

🎨
Click-to-prop color swaps
Every distinct color in your SVG becomes a swatch. Click to cycle through static / currentColor / exposed prop — the output rewrites in real time. Other converters leave you grepping for hex values manually.
👀
Live preview on light + dark
See the rendered SVG next to two swatches (white card, near-black card) so you can verify your color choices survive both themes before you copy.
🔧
forwardRef + TypeScript + size prop
The default output is a real component, not just JSX: wrapped in forwardRef so consumers can ref it, typed with SVGProps<SVGSVGElement> if TypeScript is on, and reshaped so size={32} works.
🔒
100% in-browser
Your SVG never leaves the page. Drag-drop a file from your desktop, paste a Figma export, or load an example — the conversion runs entirely in the browser.

How to use this converter

01
Paste or drop an SVG
Paste markup into the left pane, drop a .svg file from your desktop, or load one of the examples (a lucide-style icon, a Figma export, a gradient logo, or a multi-color icon).
02
Pick how colors should behave
Click each color swatch below the editor to cycle through: keep static → use currentColor (inherits from the parent text color) → expose as a named prop (color1, color2, …). The live preview reflects each click.
03
Tune the component shape
Toggle component name, forwardRef, TypeScript, size prop, and Clean output (strips xmlns, version, Inkscape namespaces, comments, XML prolog). Each toggle re-renders the output instantly.
04
Copy or download
Switch between the Component view and the Bare JSX view at the top of the output pane. Copy to the clipboard or Download as a .jsx or .tsx file named after the component.

Common SVG → JSX renames

Every hyphenated SVG attribute (stroke-width, fill-rule, clip-path, …) and every HTML reserved-word attribute (class, for, tabindex, …) must be renamed for React to render the element. The converter handles 80+ such renames automatically; here are the ones you'll hit most.

SVG / HTMLJSXWhy
classclassNameReserved word in JS
stroke-widthstrokeWidthHyphenated SVG attr → camelCase
fill-rulefillRuleHyphenated SVG attr → camelCase
clip-pathclipPathHyphenated SVG attr → camelCase
xlink:hrefxlinkHrefNamespaced → camelCase. Per SVG 2 you can use plain href.
viewboxviewBoxReact enforces camelCase even though SVG is case-insensitive
tabindextabIndexHTML attr → camelCase
style="fill:red"style={{ fill: "red" }}Inline CSS → object literal with camelCase keys
{/* comment */}HTML comment → JSX block comment
Void-like SVG elements must self-close in JSX
=

What the output looks like

Component
import { forwardRef } from 'react';

export const Check = forwardRef(
  function Check({ size = 24, color1 = '#7C6CFF', ...rest }, ref) {
    return (
      <svg ref={ref} width={size} height={size} viewBox="0 0 48 48" fill="none" {...rest}>
        <rect x="4" y="4" width="40" height="40" rx="8" fill={color1}/>
        <path d="M16 24L22 30L34 18" stroke="white" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"/>
      </svg>
    );
  }
);
Bare JSX
<svg viewBox="0 0 48 48" fill="none">
  <rect x="4" y="4" width="40" height="40" rx="8" fill={color1}/>
  <path d="M16 24L22 30L34 18" stroke="white" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
Usage
<Check size={32} color1="var(--brand)" className="text-white" />

Pro tips

01
Use currentColor for monochrome icons
Single-color icons (lucide, Heroicons, Phosphor) work best when the fill or stroke is currentColor — the icon inherits whatever text-color the parent sets, so the same component recolors itself across the app without prop drilling.
02
Expose multi-color icons as props
For a brand mark with two or three accent colors, click each swatch through to "prop". The component gets color1, color2, color3 props with the original colors as defaults — so you can recolor the mark per theme without forking the file.
03
Set viewBox; drop width/height
A viewBox lets the icon scale cleanly to any size. With the "size prop" toggle on, hardcoded width/height attributes are replaced with a single size prop (default 24) — the consumer sets size={48} and everything else stays proportional.
04
Watch the issues panel
It flags inline <style> blocks, <script> tags, missing viewBox, Inkscape/Sodipodi metadata, and event handlers. None of these break the output, but each one is a cleanup task worth knowing about before you ship.
?

Frequently asked questions

01

How is this different from svgr or svg2jsx?

Most online SVG-to-JSX converters output a JSX snippet. This one outputs a real React component: wrapped in forwardRef, optionally typed with SVGProps<SVGSVGElement>, and reshaped so a size prop works. The standout feature is the color extraction grid — every distinct color in your SVG appears as a clickable swatch, and clicking cycles through static / currentColor / exposed prop with the output rewriting in real time. Other tools leave that cleanup as a manual grep-and-replace.

02

What's currentColor and when should I use it?

currentColor is a CSS keyword that resolves to the parent element's text color at render time. For monochrome icons (Lucide, Heroicons, Phosphor), setting fill or stroke to currentColor means the icon picks up whatever color={...} or className adds to its parent — so the same component recolors itself across the app without any prop drilling. Use it for any icon that should always match nearby text.

03

How does the multi-color prop exposure work?

For brand marks or icons with two or three accent colors, click each color swatch through to 'prop' mode. The converter generates color1, color2, color3 props on the component with the original hex values as defaults. Consumers can then recolor the mark per theme — for example <Logo color1='var(--brand)' color2='var(--accent)' /> — without forking the SVG file or maintaining multiple variants.

04

Does the output work with TypeScript?

Yes — toggle the TypeScript option to emit a .tsx file with a typed Props interface that extends React's SVGProps<SVGSVGElement>. Every prop you expose (size, color1, color2, …) is typed, and the forwardRef generic is parameterized so the ref is typed as SVGSVGElement. The default is JavaScript output, which is fine for most React projects that don't strictly require .tsx for components.

05

Are my SVGs uploaded anywhere?

No. Conversion runs entirely in your browser — paste, drop, or load an example, all of it stays on your device. There's no network request involved, no telemetry on the conversion contents, and no analytics on what you paste. The site itself uses cookieless analytics (page views only) but the tool never reads or transmits your SVG data.

06

What if my SVG has Inkscape or Sodipodi metadata?

Turn on 'Clean output' (it's on by default) and the converter strips Inkscape and Sodipodi namespace attributes (sodipodi:nodetypes, inkscape:label, inkscape:groupmode, etc.) along with xmlns, version, the XML prolog, and HTML comments. The issues panel below the converter flags this metadata when it's present so you know it's being stripped.

Search CodeFronts

Loading…