SVGR Alternative: SVGR vs Online Converter
Looking for an SVGR alternative? Compare SVGR in your build with an online converter: setup, repeatability, review, defaults like SVGO, and when to use each.
By SVG to React. Published . Updated .
People who search for an SVGR alternative usually want one of two things. Some want to avoid adding a dependency and a build step just to convert a few icons. Others have been burned by a default, such as a missing viewBox, and want something more predictable. An online converter can solve the first problem. The second is solved by understanding the defaults, whichever tool you use. This post compares the two workflows honestly, including the fact that many online converters run SVGR underneath.
What SVGR is
SVGR is an open source library that turns SVG markup into React components. The core package parses the SVG and rebuilds it as JSX. Plugins add the optional steps: @svgr/plugin-svgo optimizes the markup, @svgr/plugin-jsx produces the component, and @svgr/plugin-prettier formats the result. Around the core sit several entry points:
@svgr/cliconverts files or folders from the command line.@svgr/webpackconverts.svgimports during a webpack build. Next.js's Turbopack can run the same loader.vite-plugin-svgr, a community plugin, does the same for Vite. By default it applies to imports that end in?react.@svgr/corecan be called from your own scripts, or from a web page.
The last point matters for this comparison. The SVG to React converter on this site calls @svgr/core with the JSX plugin in your browser. So does the TSX page. Choosing it over SVGR is a choice of workflow, not of engine.
Two workflows
SVGR in the build
The .svg file stays in the repository, and every import becomes a component when the bundle is built. Add an icon by dropping a file into a folder. Every icon goes through the same options on every build, and nobody has to remember which settings were used last time.
Convert once, commit the component
The .svg is converted once, either with the CLI or in a converter, and the resulting .jsx or .tsx file is committed. The component is ordinary code. It is reviewed in pull requests, and it can be edited by hand, for example to add a title prop or a second color prop. The build needs no SVG loader at all.
Both are legitimate. The list below is the honest version of the comparison.
- Setup. Build-time SVGR needs a loader or plugin, its config, and type declarations for
.svgimports. An online converter needs nothing. The CLI is in between: one command, no build changes. - Repeatability. A build step applies the same config to every file forever. A converter applies whatever is selected in the page at that moment. If ten people convert icons by hand, expect small differences unless you write the settings down.
- Review. Committed components show their exact markup in a diff. A build transform shows the SVG diff, and the generated component only exists in the bundle.
- Custom edits. Committed components can be changed by hand. Build output cannot. Changes have to go into an SVGR template or config, which then applies to every icon.
- Volume. Hundreds of icons that change often belong in an automated step. A dozen icons that change twice a year do not need one.
- Privacy. A build runs on your machines. An online converter may or may not upload the file. The converters on this site process it in the browser. Check the policy of any other site before pasting artwork you do not own.
The default that surprises people: SVGO and viewBox
The SVGR CLI and the webpack loader run SVGO by default before printing the component. SVGR 8's SVGO plugin depends on SVGO 3. In SVGO 3, preset-default includes removeViewBox, which drops viewBox when it matches the width and height. It also includes removeTitle, which deletes <title> elements. A component without a viewBox crops instead of scaling when you change its size. That clashes with the icon option, which sets width and height to 1em. A component without its title loses its accessible name.
SVGO 4 removed both plugins from preset-default. Until your SVGR version uses SVGO 4, override them:
// svgr.config.js
module.exports = {
icon: true,
typescript: true,
svgoConfig: {
plugins: [
{
name: "preset-default",
params: {
overrides: {
// SVGO 3, used by SVGR 8, would otherwise drop viewBox and <title>
removeViewBox: false,
removeTitle: false,
},
},
},
],
},
};The other option is to turn SVGO off in SVGR and optimize the files separately, with settings you can see:
# Convert a folder once and commit the output
npx @svgr/cli --typescript --icon --out-dir src/icons -- assets/icons
# Skip SVGO if you optimize files in a separate step
npx @svgr/cli --no-svgo --out-dir src/icons -- assets/iconsThe converter on this site leaves Optimize off by default. When you turn it on, it runs SVGO 4's preset-default, which keeps viewBox. The guide to what the Optimize pass keeps lists the details. Whatever tool you use, the rule is the same: know which SVGO version runs and which plugins it applies.
Build integration examples
If you choose the build route in Next.js, the loader is configured in next.config.js. With Turbopack, a rule maps .svg files to the SVGR loader:
// next.config.js: Turbopack (Next.js 15.3 and later)
module.exports = {
turbopack: {
rules: {
"*.svg": { loaders: ["@svgr/webpack"], as: "*.js" },
},
},
};Webpack builds use a module.rules entry instead. Next.js also handles .svg imports for next/image, so the rule should not break imports that still expect a URL. The Next.js-specific choices, including when not to use a loader at all, are in SVG in Next.js: Inline, img, or Component.
Other alternatives that skip components
Not every SVG needs to become a React component. Three alternatives are worth knowing:
- An img tag with the file from your static folder. It is cached separately and costs no JavaScript, but you cannot style its inside.
- An SVG sprite. One file contains many
<symbol>elements, and each icon is drawn with<use href="/sprite.svg#check" />. The file is cached once. Icons inheritcurrentColorthrough the use element, but styling individual paths inside the symbol from outside is limited. - A CSS data URI for small decorative graphics such as background patterns. See SVG to Data URI in CSS: Encoding Rules.
A practical recommendation
For a small, stable set of icons, convert them once and commit the components. Paste each file into the converter, or drop a folder into the batch tool, which takes up to 50 files and returns one zip with an optional index file. For a large set maintained by designers, put SVGR in the build with a config file checked into the repository. That way the defaults are visible and the same for everyone. Either way, look at the first few components it produces before you trust it with the rest.
Questions
Is an online converter a real SVGR alternative?
For one-off icons, yes. The workflow is different, not the engine: many online converters, including this site, run SVGR itself. What you give up is automation. A build step converts every file the same way on every build, and an online tool converts what you paste.
Why did SVGR remove my viewBox?
SVGR's SVGO plugin in version 8 depends on SVGO 3, whose preset-default includes removeViewBox. That plugin drops viewBox when it matches width and height. Override removeViewBox to false in svgoConfig, or turn SVGO off in SVGR and optimize the files separately.
Can I mix both approaches in one project?
Yes, but pick one source of truth per folder. Converted components committed to the repo are plain code that reviewers can read. Files transformed at build time stay as .svg in the repo. Mixing both for the same icon set leads to two components that drift apart.
Is my SVG uploaded when I use an online converter?
That depends on the site. The converters here run in your browser and do not send the SVG to a server. Other sites may process files on their servers, so check their privacy policy before pasting artwork you are not allowed to share.