What is SVG?
SVG explained: the XML structure behind vector graphics, why viewBox matters, what SVGO actually optimizes, and converting SVG to JSX.
SVG (Scalable Vector Graphics) describes images as XML markup, shapes, paths, and text defined by coordinates and math, instead of a grid of pixels. That's the whole difference from PNG or JPEG: a raster image is fixed resolution and blurs when scaled up, an SVG is resolution-independent and renders crisp at any size, from a 16px favicon to a full-bleed hero graphic.
Because it's XML, an SVG is also just text: readable, diffable in version control, stylable with CSS, and scriptable with JavaScript the same way any other DOM node is. A raster image can't do any of that.
Anatomy of an SVG file
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M12 2L2 7l10 5 10-5-10-5z" fill="currentColor"/>
<circle cx="12" cy="17" r="3" stroke="currentColor" stroke-width="1.5"/>
</svg>viewBox="min-x min-y width height" defines the internal coordinate system: it's what lets the SVG scale to fill whatever box CSS gives it, independent of any width/height attribute on the root element. <path d="..."> is the workhorse element, its d attribute is a compact command language (M = move to, L = line to, C = curve, Z = close path) that most shapes eventually compile down to, even ones drawn with <circle> or <rect> in the source file.
What SVGO actually optimizes
Files exported from Figma, Illustrator, or Sketch carry a lot that never affects rendering: editor namespaces, <metadata> blocks, XML comments, and coordinate precision far beyond what a screen can display (12.847293847 instead of 12.85). SVGO's default preset strips all of it while keeping the rendered output pixel-identical, which is typically a 30-60% size reduction on tool-exported icons.
One thing worth knowing if you've used SVGO before: viewBox removal is not part of the default preset as of SVGO v4 (this site's version). It used to be, in v2 and v3, which caused real problems, dropping viewBox while a fixed width/height stuck around meant the SVG stopped scaling to fill a responsive container. If you're troubleshooting an SVG that lost its viewBox somewhere in a build pipeline, that's almost always an older SVGO version or an explicit override, not this tool.
Optimizing is not the same as sanitizing. SVG can carry a <script> element or onload/onclick handlers, and the default preset doesn't touch either, that's a file-size pass, not a security pass. The SVG Optimizer on this site has a separate "strip scripts & event handlers" toggle for exactly this reason, on by default, worth keeping on unless you have a specific reason not to.
SVG in JSX
Pasting raw SVG markup into a React component almost works, and then fails on a handful of attributes: class is a reserved word in JSX (it becomes className), kebab-case attributes like stroke-width aren't valid JSX and need strokeWidth, and an inline style="fill:red" string has to become a JS object, style={{ fill: 'red' }}.
The SVG to JSX converter on this site handles that rename pass automatically and can wrap the result in a named functional component. Vue and Svelte don't need an equivalent tool for this specific problem: SVG is already valid template syntax in both, so there's no attribute-renaming step to do.
Try it now
Frequently asked questions
Not with a current SVGO. removeViewBox used to ship as part of the default preset in SVGO v2 and v3, which was controversial: dropping viewBox while keeping width/height fixes the rendered size and stops the SVG from scaling to fill a responsive container. As of SVGO v4, removeViewBox is no longer included in preset-default at all, it has to be opted into explicitly.
This site's optimizer runs SVGO v4, so viewBox survives a default optimization pass. If you're troubleshooting an SVG that lost its viewBox somewhere else in your pipeline, check whether that tool is still on SVGO v2/v3 defaults or has removeViewBox explicitly enabled.