react-native-svg
`react-native-svg` brings SVG drawing primitives to React Native on iOS, Android, macOS, Windows, and compatible web setups. Components such as `Svg`, `Path`, `Circle`, `Text`, gradients, masks, clip paths, and images render through native platform implementations while keeping a JSX-shaped API. It can also parse XML or CSS-bearing SVG strings and load remote SVG documents. This is a vector rendering layer, not an icon catalog, charting package, or full browser SVG engine.
This is the default React Native building block for real SVG assets and custom vector UI. Check the React Native compatibility table first, and use an icon pack or Skia when the problem is respectively simpler or much more graphics-heavy.
Use it if
- You need custom resolution-independent illustrations, icons, diagrams, or charts in React Native
- Design assets already arrive as SVG paths and can be converted to React components
- You need gradients, clipping, masks, text paths, reusable definitions, or shape-level touch events
- Your application targets Expo or maintained React Native versions across more than one native platform
- You only need a standard icon set: a packaged icon library avoids hand-maintained path data and gives consistent naming, sizing, and accessibility conventions
- You need arbitrary browser SVG fidelity: the README promises most SVG elements and properties, not the complete web platform, and its known issues still list Android radial-gradient focus-point behavior
- Your app is pinned to an older React Native release: version 15.15.5 belongs to the 15.13+ line whose compatibility table requires React Native 0.78 or newer
- You want zero native integration outside Expo: React Native CLI projects still install native code and run CocoaPods on iOS, while Windows needs its own initialization and build path
- You need GPU-heavy animation, filters, particles, or canvas-style drawing: a drawing engine such as React Native Skia is a better fit than driving a large, frequently changing SVG tree through React props
Setup reality
In an Expo project, use `npx expo install react-native-svg` so Expo chooses a compatible package; Expo already includes the native code in its client. In a React Native CLI app, install the npm package, then run `cd ios && pod install` and rebuild the native application. Version alignment is not optional: the README's table says `react-native-svg >=15.13.0` requires React Native 0.78 or newer, while older React Native apps need an older library line. Fabric support has its own history, beginning with version 13 on React Native 0.69+, so test both architecture mode and every target platform during upgrades. Raw `<svg>` files are not imported automatically. The documented `react-native-svg-transformer` route adds Metro configuration and changes asset extension handling; alternatively, convert assets to JSX with SVGR or use `SvgXml` at runtime. Web builds need Metro or webpack aliases and loaders appropriate to React Native Web. Remote `SvgUri` content adds network, caching, error, and trust concerns; use its error and fallback props and do not treat untrusted XML as a harmless image blob. Percentage sizing still needs a parent with measurable dimensions. Platform rendering differences exist, and the README asks bug reports to include a clean project, platform results, and `react-native info`; budget time to check Android and iOS rather than approving an asset from one simulator.
Patterns
Draw scalable basic shapesdraw-basic-shapes
import Svg, { Circle, Rect } from 'react-native-svg';
<Svg width={160} height={100} viewBox="0 0 160 100">
<Rect x={0} y={0} width={160} height={100} rx={12} fill="#eef2ff" />
<Circle cx={80} cy={50} r={28} fill="#4f46e5" />
</Svg>;A `viewBox` separates drawing coordinates from displayed size and keeps the artwork scalable.
Render an SVG pathdraw-path
import Svg, { Path } from 'react-native-svg';
<Svg width={48} height={48} viewBox="0 0 24 24">
<Path
d="M12 2 22 20H2L12 2Z"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinejoin="round"
/>
</Svg>;React Native SVG props use JSX casing such as `strokeWidth`, not dashed XML attribute names.
Fill a shape with a linear gradientapply-linear-gradient
import Svg, { Defs, LinearGradient, Stop, Rect } from 'react-native-svg';
<Svg width={240} height={80}>
<Defs>
<LinearGradient id="brand" x1="0%" y1="0%" x2="100%" y2="0%">
<Stop offset="0%" stopColor="#7c3aed" />
<Stop offset="100%" stopColor="#06b6d4" />
</LinearGradient>
</Defs>
<Rect width="100%" height="100%" rx={12} fill="url(#brand)" />
</Svg>;Gradient definitions belong inside `Defs` and are referenced with a matching `url(#id)`.
Clip an image to a circleclip-content
import Svg, { Defs, ClipPath, Circle, Image } from 'react-native-svg';
<Svg width={120} height={120}>
<Defs>
<ClipPath id="avatarClip">
<Circle cx={60} cy={60} r={56} />
</ClipPath>
</Defs>
<Image
href={{ uri: avatarUrl }}
width={120}
height={120}
preserveAspectRatio="xMidYMid slice"
clipPath="url(#avatarClip)"
/>
</Svg>;Remote raster images still need normal network permissions, dimensions, caching decisions, and error handling around the component.
Reuse a shape with Defs and Usereuse-defined-shape
import Svg, { Defs, G, Circle, Use } from 'react-native-svg';
<Svg width={140} height={60}>
<Defs>
<G id="dot">
<Circle cx={10} cy={10} r={8} fill="#16a34a" />
</G>
</Defs>
<Use href="#dot" x={10} y={20} />
<Use href="#dot" x={50} y={20} />
<Use href="#dot" x={90} y={20} />
</Svg>;The `href` includes `#` and must match a unique `id` inside the same SVG document.
Render positioned SVG textrender-svg-text
import Svg, { Text, TSpan } from 'react-native-svg';
<Svg width={240} height={80}>
<Text x={12} y={28} fill="#111827" fontSize={18} fontWeight="600">
Revenue
<TSpan x={12} dy={26} fill="#059669" fontSize={22}>$42,800</TSpan>
</Text>
</Svg>;SVG text layout is not React Native `Text` layout; test font availability and baseline behavior on each platform.
Attach a touch event to a shapehandle-shape-press
<Circle
cx={50}
cy={50}
r={40}
fill="tomato"
onPress={() => selectPoint('center')}
/>;The usage guide also lists `onPressIn` and `onPressOut`; provide a suitable hit target and accessible surrounding control.
Load an SVG document from a URIload-remote-svg
import { SvgUri } from 'react-native-svg';
<SvgUri
width={120}
height={120}
uri={imageUrl}
onError={(error) => console.warn(error)}
fallback={<PlaceholderIcon />}
/>;Remote loading needs an error path and trust decision; it is slower and less predictable than a bundled component.
Render an SVG XML stringrender-svg-xml
import { SvgXml } from 'react-native-svg';
const xml = `<svg viewBox="0 0 24 24"><path fill="#2563eb" d="M4 4h16v16H4z"/></svg>`;
<SvgXml xml={xml} width={48} height={48} />;Runtime XML parsing costs more than importing a compiled component and should not be fed unreviewed content casually.
Render an SVG string containing CSSrender-css-svg
import { SvgCss } from 'react-native-svg';
<SvgCss
xml={`<svg viewBox="0 0 20 20"><style>.dot{fill:#e11d48}</style><circle class="dot" cx="10" cy="10" r="8"/></svg>`}
width={40}
height={40}
/>;Use `SvgCss` rather than `SvgXml` when embedded CSS rules need parsing.
Import an SVG file through the transformerimport-svg-file
import Logo from './logo.svg';
export function HeaderLogo() {
return <Logo width={120} height={32} />;
}This syntax requires `react-native-svg-transformer` plus the documented Metro asset and source extension configuration.
Transform a group of shapesgroup-transformations
import Svg, { G, Rect, Circle } from 'react-native-svg';
<Svg width={160} height={100} viewBox="0 0 160 100">
<G transform="translate(30 10) rotate(8 50 40)" opacity={0.9}>
<Rect x={0} y={0} width={100} height={70} rx={8} fill="#fde68a" />
<Circle cx={50} cy={35} r={16} fill="#f59e0b" />
</G>
</Svg>;Group props and transformations affect children; keep coordinate systems simple when touch targets must match artwork.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| react-native-vector-icons | npm | You need a maintained catalog of font-backed application icons rather than arbitrary SVG drawings |
| @shopify/react-native-skia | npm | You need high-performance canvas drawing, shaders, filters, or animation-intensive graphics |
| react-native-webview | npm | You must render complex browser-authored SVG or HTML content with web-engine behavior |