One SVG to Rule Them All: The Dynamic Way
When you ship icons in a React Native app, it's tempting to export a separate file for every stroke width and color. You don't have to. SVG's presentation attributes inherit, and react-native-svg-transformer runs your .svg files through SVGR, which spreads incoming component props onto the root <svg> element. Pass color and strokeWidth as props once; SVG inheritance handles the rest.
Setup
1bun add react-native-svg
2bun add -d react-native-svg-transformerRoute .svg files through the transformer in metro.config.js (RN 0.72+ form):
1const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config')
2
3const defaultConfig = getDefaultConfig(__dirname)
4const { resolver: { sourceExts, assetExts } } = defaultConfig
5
6module.exports = mergeConfig(defaultConfig, {
7 transformer: {
8 babelTransformerPath: require.resolve('react-native-svg-transformer'),
9 },
10 resolver: {
11 assetExts: assetExts.filter((ext) => ext !== 'svg'),
12 sourceExts: [...sourceExts, 'svg'],
13 },
14})The icon file
Strip everything you'd otherwise hard-code. Use currentColor for the stroke and omit stroke-width so it inherits from the prop:
1<!-- MyIcon.svg, an X -->
2<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
3 <path stroke="currentColor" d="M7 7l10 10M7 17l10-10" />
4</svg>Use it
1import MyIcon from './path/to/MyIcon.svg'
2
3export default function App() {
4 return (
5 <View>
6 <MyIcon width={24} height={24} color="red" strokeWidth={2} />
7 </View>
8 )
9}What's actually happening:
- SVGR's default
expandPropsspreads every prop you pass to<MyIcon>onto the generated root<Svg>element. react-native-svgresolvescurrentColoron descendants against the nearest ancestor'scolorprop.color="red"on<Svg>paints the stroke red.- SVG attribute inheritance carries
stroke-widthfrom<Svg>down to any<path>that hasn't set its own.strokeWidth={2}on the component is the only place stroke width is defined, so every path takes it.
The same pattern works for any inheritable presentation attribute — fill, stroke-linecap, stroke-linejoin, stroke-opacity, font-family. Strip them from the source SVG, pass them as component props.