Library / SDK
kristerkari/react-native-svg-transformer avatar
kristerkari/react-native-svg-transformer

react-native-svg-transformer: Metro Integration for SVG Components

Import SVG files in your React Native project the same way that you would in a Web application.

1,739 stars122 forksJavaScriptMIT

At a glance

What is it?
react-native-svg-transformer converts SVG imports into React Native components through Metro and SVGR. It is aimed at React Native developers who want reusable vector assets, including projects using Expo, TypeScript and Jest, but it depends on compatible versions of React Native and react-native-svg.
Who is it for?
Adopt it when the application imports SVG files as React components and can add Metro configuration plus the react-native-svg peer dependency. Do not treat it as a general SVG editor, an Expo replacement or a Jest asset loader, since those cases require separate setup.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Why react-native-svg-transformer exists in a React Native build

React Native and the web use different asset pipelines, so an SVG that can be imported by a web application does not automatically become a usable React Native component. react-native-svg-transformer addresses that gap by connecting Metro module resolution with SVGR. The resulting import can be used as a React component, which gives application code ordinary props such as width and height instead of treating the file as an opaque image asset.

The intended users are developers who already use React Native and react-native-svg and want one component-oriented asset workflow across native and web code. The project does not replace react-native-svg. The README identifies that library as a prerequisite, and package.json declares it as a peer dependency. The transformer handles file transformation and module integration, while react-native-svg supplies the native SVG component model that the generated output depends on.

The repository package description is deliberately narrow: "SVG transformer for react-native". Its published entry points include index.js, expo/index.js and react-native/index.js. Based on that layout and the README configuration, the project is a build-time integration rather than a component library that adds visible controls, animation APIs or SVG editing features.

Metro resolution and SVGR's transformation path

The central mechanism is a change to Metro configuration. The resolver removes svg from assetExts and adds svg to sourceExts. That distinction is important. Treating SVG as an asset makes Metro return an asset reference, while treating it as a source extension lets the configured transformer process the imported file as code.

The transformer path also depends on the project environment. Expo projects use react-native-svg-transformer/expo, while React Native projects use react-native-svg-transformer/react-native. The project provides separate implementations for those contexts, visible in the package.json files list. The README also documents projects that use Expo modules without expo-cli, where the default transformer selection may require explicitly selecting the React Native or Expo transformer path.

SVGR performs the SVG-to-React transformation. Configuration is supported through a root .svgrrc file, including replaceAttrValues. For example, a hex fill can be replaced with {props.fill}, allowing a caller to change the color of a path at runtime. This is useful for icons, but it also means one transformation rule applies to every SVG processed by that configuration. The project does not document per-file SVGR configuration in the README.

Installing the transformer and configuring Expo

First install react-native-svg separately, following the installation instructions linked by the README. Then install the transformer as a development dependency:

sh
npm install --save-dev react-native-svg-transformer

The equivalent Yarn command documented by the project is:

sh
yarn add --dev react-native-svg-transformer

For Expo SDK v41.0.0 or newer, merge the following configuration into metro.config.js, creating that file if necessary. The default config supplies the existing transformer and resolver, so the merge preserves the project's Metro settings:

js
const { getDefaultConfig } = require("expo/metro-config");

module.exports = (() => {
  const config = getDefaultConfig(__dirname);
  const { transformer, resolver } = config;

  config.transformer = {
    ...transformer,
    babelTransformerPath: require.resolve("react-native-svg-transformer/expo")
  };
  config.resolver = {
    ...resolver,
    assetExts: resolver.assetExts.filter((ext) => ext !== "svg"),
    sourceExts: [...resolver.sourceExts, "svg"]
  };

  return config;
})();

After Metro restarts, an SVG file can be imported inside a component. The README's usage example is:

jsx
import Logo from "./logo.svg";

The imported value is then rendered as a component with dimensions:

jsx
<Logo width={120} height={40} />

The result should be an SVG-backed React component, not a normal web URL or image asset reference. The README does not document a separate cache-clearing command for this setup.

React Native, TypeScript and Jest integration points

For React Native v0.72.1 or newer, the README uses @react-native/metro-config and mergeConfig. It keeps the default resolver settings while replacing the Babel transformer path and changing how svg is classified:

js
const { getDefaultConfig, mergeConfig } = require("@react-native/metro-config");

const defaultConfig = getDefaultConfig(__dirname);
const { assetExts, sourceExts } = defaultConfig.resolver;

const config = {
  transformer: {
    babelTransformerPath: require.resolve("react-native-svg-transformer/react-native")
  },
  resolver: {
    assetExts: assetExts.filter((ext) => ext !== "svg"),
    sourceExts: [...sourceExts, "svg"]
  }
};

module.exports = mergeConfig(defaultConfig, config);

For React Native v0.59 or newer, the documented configuration uses metro-config and an asynchronous default configuration. The package.json peer dependency confirms a minimum React Native version of 0.59.0 and a minimum react-native-svg version of 12.0.0. This is a compatibility boundary, not a promise that every combination above those minima will behave identically.

TypeScript projects need a declaration that maps the SVG module to a React component accepting SvgProps. Create or update declarations.d.ts with:

ts
declare module "*.svg" {
  import React from "react";
  import { SvgProps } from "react-native-svg";
  const content: React.FC<SvgProps>;
  export default content;
}

Jest is a separate boundary. The README says that tests importing SVG files need a mock and a moduleNameMapper entry. The mock file contains:

js
module.exports = "SvgMock";

The Jest configuration maps svg imports to that file:

js
module.exports = {
  moduleNameMapper: {
    "\\.svg": "<rootDir>/__mocks__/svgMock.js"
  }
};

This setup lets Jest avoid relying on the normal SVG transformation path during tests. It does not make Jest render the real SVG component.

SVGR options and runtime fill control

The transformation behavior can be changed through .svgrrc in the project root. The README shows a static color replacement from red to currentColor:

json
{
  "replaceAttrValues": {
    "red": "currentColor"
  }
}

For dynamic color control, the documented configuration replaces a matching hex value with the props reference:

json
{
  "replaceAttrValues": {
    "#000": "{props.fill}"
  }
}

The SVG itself must contain the matching fill value on its path:

xml
<path d="M2.965 6.0925C4.045 8.215 ..." fill="#000"/>

After transformation, the README gives this component usage:

jsx
<Logo width={120} height={40} fill={"any color"} />

The feature has a clear failure mode. If the SVG uses a different attribute, casing or color value, the replacement rule will not match it. The README does not claim automatic detection of every fill declaration. Also, changing a root configuration affects every SVG processed under that configuration, so a project with many differently colored assets should review the .svgrrc before assuming a global replacement is appropriate.

Maintenance, package boundaries and practical limits

The repository is not archived. Its last push was on 2026-10-16, and the listed recent releases include v1.5.3 dated 2026-01-25, v1.5.2 dated 2025-11-06 and v1.5.1 dated 2025-05-02. The package uses the MIT license. The repository includes CHANGELOG.md and LICENSE, and package.json identifies the license as MIT, but this review does not interpret the license terms or provide legal advice.

The package's runtime peer requirements are the first practical constraint. A project using React Native older than 0.59.0 or react-native-svg older than 12.0.0 falls outside the declared range. The dependency list also shows that transformation behavior is delegated to @svgr/core, @svgr/plugin-jsx and @svgr/plugin-svgo, with caret ranges. Upgrading the transformer can therefore coincide with changes in those dependency ranges and in the generated output. The repository does not provide a compatibility matrix beyond the documented peer versions and Metro configuration examples.

There is also no README documentation for remote SVG URLs, SVG sanitization, unsupported SVG features, caching behavior or rollback procedures. Those are real evaluation boundaries. The project is a Metro and Jest integration package, not a complete policy for accepting untrusted SVG content. A team that only needs static PNG or JPEG assets, or that uses a bundler other than Metro with no equivalent transformer path, should not add it merely because the asset format is SVG.

Choosing react-native-svg-transformer against a direct import approach

The direct alternative is to keep SVG files as ordinary React Native assets and render them through the asset system. react-native-svg-transformer takes a different route: it changes Metro's source extensions, selects an SVGR-backed transformer and emits a React component. The direct approach avoids a custom Babel transformer but does not provide the documented component import syntax or SVGR fill replacement behavior.

Another alternative is to author equivalent icons as JavaScript or TypeScript components. That approach gives the application direct control over props without adding an SVG transformation step, but it duplicates asset content outside the SVG workflow. The transformer is therefore most relevant when the source of truth should remain an SVG file and several call sites need to pass component props such as width, height or fill.

The trade-off is build configuration. Expo and React Native need different transformer entry points, older projects need a different Metro config, and Jest needs an explicit mock. A project with only a handful of static icons may find direct authoring simpler. A project with many imported SVGs and consistent runtime styling gets more benefit from the documented SVGR integration.

Editorial conclusion

Adopt it when the application imports SVG files as React components and can add Metro configuration plus the react-native-svg peer dependency. Do not treat it as a general SVG editor, an Expo replacement or a Jest asset loader, since those cases require separate setup. Verify the installed React Native and react-native-svg versions, confirm the transformer path for the project type, and inspect an actual transformed component before migrating assets.

Frequently asked questions

How do I install react-native-svg-transformer?

Install react-native-svg first, then run `npm install --save-dev react-native-svg-transformer` or `yarn add --dev react-native-svg-transformer`. You must also configure Metro so SVG files are treated as source files and routed through the correct transformer.

Which Metro transformer should I use in Expo or React Native?

Use `react-native-svg-transformer/expo` for Expo SDK v41.0.0 or newer and `react-native-svg-transformer/react-native` for React Native projects. Projects using Expo modules without expo-cli may need to select one of these paths explicitly.

How do I change the fill color of an imported SVG?

Configure `replaceAttrValues` in the root `.svgrrc` file and make sure the SVG path contains the matching value. The README shows replacing `#000` with `{props.fill}`, then passing `fill` when rendering the component.

Official sources

  1. Issues
  2. kristerkari/react-native-svg-transformer on GitHub
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/kristerkari-react-native-svg-transformer.svg)](https://hysenlabs.com/projects/kristerkari-react-native-svg-transformer)

Was this useful?