490 words
2 minutes
How to Configure SVG Support in React Native with react-native-svg-transformer

Working with icons in React Native can be a pain — especially if you want to use SVGs instead of PNGs. Luckily, there’s a clean way to make it all work seamlessly with react-native-svg-transformer. In this article, I’ll show you how to set it up, make it work with TypeScript and Jest, and even add custom props for your SVGs like fill or stroke.


💡 Step 1 — Install the Transformer#

First things first, let’s add the dependency that will allow Metro to transform .svg files into React components:

Terminal window
yarn add react-native-svg-transformer

or, if you prefer npm:

Terminal window
npm install react-native-svg-transformer

That’s it. The real magic starts in the config.


⚙️ Step 2 — Update Your metro.config.js#

We need to tell Metro how to handle .svg files instead of treating them like regular assets. Here’s the full config that works perfectly with Expo or plain React Native:

const { getDefaultConfig } = require("expo/metro-config")
module.exports = (() => {
const config = getDefaultConfig(__dirname)
const { transformer, resolver } = config
config.transformer = {
...transformer,
getTransformOptions: async () => ({
transform: {
inlineRequires: true,
},
}),
// 👇 The magic line
babelTransformerPath: require.resolve("react-native-svg-transformer/expo"),
}
config.resolver = {
...resolver,
// Remove `.svg` from asset extensions
assetExts: resolver.assetExts.filter((ext) => ext !== "svg"),
// Add `.svg` to source extensions
sourceExts: [...resolver.sourceExts, "cjs", "svg"],
}
return config
})()

Now Metro will know how to parse .svg files as React components.


🧩 Step 3 — Add TypeScript Declarations#

If you’re using TypeScript, it’ll complain about importing SVGs unless you tell it what to expect. Create a declarations.d.ts file in your root directory and add:

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

Now, TypeScript knows that .svg files are valid React components that accept SvgProps.


🧪 Step 4 — Set Up Jest (Optional but Handy)#

If you’re testing your components with Jest, you’ll need a mock for .svg imports. In your jest.config.ts, add:

transformer: {
// your existing config
},
moduleNameMapper: {
"\\.svg": "<rootDir>/__mocks__/svgMock.js",
},

Then, create a simple mock file in __mocks__/svgMock.js:

module.exports = "SvgMock"
module.exports.ReactComponent = "SvgMock"

Now your tests won’t break when SVGs are imported.


🧠 Step 5 — Try It Out#

Let’s add a test icon called menu.svg

Create a new file called svg.ts to export it easily:

import MenuSVG from "assets/svgs/menu.svg"
export { MenuSVG }

Now you can import it anywhere:

import { MenuSVG } from "path/to/svg"
<MenuSVG width={24} height={24} />

Clean and simple.


🎨 Step 6 — Add Custom Props to Your SVGs#

Want to dynamically change your SVG colors? Easy. Create a .svgrrc file at the root of your project and add:

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

This lets you override the hardcoded fill color in the SVG. Now you can do this:

<MenuSVG fill={colors.palette.neutral100} />

Boom 💥 — fully dynamic icons.


✅ Conclusion#

That’s it! You’ve just set up full SVG support in your React Native app — with Metro, TypeScript, Jest, and prop customization. No more converting icons or struggling with weird configs.

SVGs now behave like first-class React components — reusable, customizable, and perfect for a scalable design system.