Documentation Index
Fetch the complete documentation index at: https://mintlify.com/shopify/react-native-skia/llms.txt
Use this file to discover all available pages before exploring further.
React Native Skia provides comprehensive support for rendering SVG (Scalable Vector Graphics) files with the ImageSVG component.
ImageSVG Component
The ImageSVG component renders SVG graphics on the canvas.
Props
| Name | Type | Description |
|---|
| svg | SkSVG | SVG image instance loaded with useSVG |
| x | number | Optional x coordinate of the SVG container |
| y | number | Optional y coordinate of the SVG container |
| width | number | Width when root SVG uses relative units |
| height | number | Height when root SVG uses relative units |
Basic Example
import { Canvas, ImageSVG, useSVG } from "@shopify/react-native-skia";
const ImageSVGDemo = () => {
const svg = useSVG(require("./assets/tiger.svg"));
if (!svg) {
return null;
}
return (
<Canvas style={{ flex: 1 }}>
<ImageSVG
svg={svg}
width={256}
height={256}
/>
</Canvas>
);
};
Loading SVG Files
From Bundle
Load SVG files from your JavaScript bundle:
import { useSVG } from "@shopify/react-native-skia";
const svg = useSVG(require("./assets/logo.svg"));
From Network
Load SVG files from a URL:
const svg = useSVG(
"https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg"
);
From String
Create SVG from inline strings:
import { Skia } from "@shopify/react-native-skia";
const svg = Skia.SVG.MakeFromString(
`<svg viewBox='0 0 290 500' xmlns='http://www.w3.org/2000/svg'>
<circle cx='145' cy='250' r='120' fill='#c02aaa'/>
</svg>`
);
From Data
Create from encoded data:
import { Skia } from "@shopify/react-native-skia";
const svgData = Skia.Data.fromBytes(svgBytes);
const svg = Skia.SVG.MakeFromData(svgData);
Positioning and Sizing
Absolute Units
If the SVG has absolute dimensions, the width/height props have no effect:
{/* SVG with width="200" height="200" in the file */}
<ImageSVG svg={svg} x={0} y={0} />
Relative Units
For SVGs with relative dimensions (percentages), use width/height:
{/* SVG with viewBox but no width/height attributes */}
<ImageSVG svg={svg} width={256} height={256} />
Positioning
<ImageSVG
svg={svg}
x={50}
y={100}
width={200}
height={200}
/>
Working with Text in SVG
Both Skia.SVG.MakeFromData and Skia.SVG.MakeFromString accept an optional font manager for custom fonts:
import { Canvas, ImageSVG, Skia, useFonts } from "@shopify/react-native-skia";
const SVGWithCustomFonts = () => {
const fontMgr = useFonts({
Roboto: [
require("./fonts/Roboto-Regular.ttf"),
require("./fonts/Roboto-Bold.ttf"),
],
});
if (!fontMgr) {
return null;
}
const svgString = `
<svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
<text x="10" y="50" font-family="Roboto" font-size="24">
Hello, World!
</text>
</svg>
`;
const svg = Skia.SVG.MakeFromString(svgString, fontMgr);
return (
<Canvas style={{ flex: 1 }}>
<ImageSVG svg={svg} width={200} height={100} />
</Canvas>
);
};
SVG Instance Methods
The SkSVG instance provides dimension methods:
const svg = useSVG(require("./assets/logo.svg"));
if (svg) {
const width = svg.width();
const height = svg.height();
console.log({ width, height });
}
Applying Effects
The ImageSVG component doesn’t follow standard painting rules. To apply effects, use the layer property:
import { Canvas, ImageSVG, Group, Paint, Blur, useSVG } from "@shopify/react-native-skia";
const SVGWithEffects = () => {
const svg = useSVG(require("./assets/logo.svg"));
return (
<Canvas style={{ flex: 1 }}>
<Group layer={<Paint><Blur blur={10} /></Paint>}>}
<ImageSVG svg={svg} width={256} height={256} />
</Group>
</Canvas>
);
};
Color Filter
import { Canvas, ImageSVG, Group, Paint, ColorMatrix, useSVG } from "@shopify/react-native-skia";
const TintedSVG = () => {
const svg = useSVG(require("./assets/icon.svg"));
return (
<Canvas style={{ flex: 1 }}>
<Group
layer={
<Paint>
<ColorMatrix
matrix={[
0, 0, 0, 0, 1, // Red
0, 1, 0, 0, 0, // Green
0, 0, 1, 0, 0, // Blue
0, 0, 0, 1, 0, // Alpha
]}
/>
</Paint>
}
>
<ImageSVG svg={svg} width={128} height={128} />
</Group>
</Canvas>
);
};
Opacity
import { Canvas, ImageSVG, Group, Paint, useSVG } from "@shopify/react-native-skia";
const TransparentSVG = () => {
const svg = useSVG(require("./assets/logo.svg"));
return (
<Canvas style={{ flex: 1 }}>
<Group opacity={0.5}>
<ImageSVG svg={svg} width={256} height={256} />
</Group>
</Canvas>
);
};
On Web, the Current Transformation Matrix (CTM) is not applied to ImageSVG because it uses browser SVG rendering:
// Transformations must be applied via Group on Web
<Group transform={[{ rotate: Math.PI / 4 }]}>
<ImageSVG svg={svg} width={256} height={256} />
</Group>
On iOS and Android, transformations work as expected:
// Works on native platforms
<ImageSVG
svg={svg}
width={256}
height={256}
transform={[{ rotate: Math.PI / 4 }]}
/>
Common Patterns
Responsive SVG
import { Canvas, ImageSVG, useSVG } from "@shopify/react-native-skia";
import { useWindowDimensions } from "react-native";
const ResponsiveSVG = () => {
const { width, height } = useWindowDimensions();
const svg = useSVG(require("./assets/background.svg"));
return (
<Canvas style={{ flex: 1 }}>
<ImageSVG svg={svg} width={width} height={height} />
</Canvas>
);
};
Centered SVG
import { Canvas, ImageSVG, useSVG } from "@shopify/react-native-skia";
const CenteredSVG = () => {
const svg = useSVG(require("./assets/icon.svg"));
const canvasSize = 256;
const svgSize = 100;
return (
<Canvas style={{ width: canvasSize, height: canvasSize }}>
<ImageSVG
svg={svg}
x={(canvasSize - svgSize) / 2}
y={(canvasSize - svgSize) / 2}
width={svgSize}
height={svgSize}
/>
</Canvas>
);
};
SVG Grid
import { Canvas, ImageSVG, useSVG } from "@shopify/react-native-skia";
const SVGGrid = () => {
const icon = useSVG(require("./assets/icon.svg"));
const size = 50;
const gap = 10;
return (
<Canvas style={{ width: 256, height: 256 }}>
{[0, 1, 2, 3].map((row) =>
[0, 1, 2, 3].map((col) => (
<ImageSVG
key={`${row}-${col}`}
svg={icon}
x={col * (size + gap)}
y={row * (size + gap)}
width={size}
height={size}
/>
))
)}
</Canvas>
);
};
Animated SVG
import { Canvas, ImageSVG, Group, useSVG } from "@shopify/react-native-skia";
import { useDerivedValue, useSharedValue, withRepeat, withTiming } from "react-native-reanimated";
import { useEffect } from "react";
const AnimatedSVG = () => {
const svg = useSVG(require("./assets/logo.svg"));
const rotation = useSharedValue(0);
useEffect(() => {
rotation.value = withRepeat(
withTiming(Math.PI * 2, { duration: 3000 }),
-1,
false
);
}, []);
const transform = useDerivedValue(() => [
{ rotate: rotation.value },
]);
return (
<Canvas style={{ width: 256, height: 256 }}>
<Group origin={{ x: 128, y: 128 }} transform={transform}>
<ImageSVG svg={svg} width={256} height={256} />
</Group>
</Canvas>
);
};
- Cache loaded SVGs with
useSVG
- Use appropriate dimensions to avoid unnecessary scaling
- Consider rasterizing complex SVGs to images
- Limit the number of SVGs rendered simultaneously
- Preload SVGs when possible
Troubleshooting
SVG Not Rendering
- Check that the SVG loaded successfully (not
null)
- Verify the SVG file is valid
- Ensure width/height are provided for relative-sized SVGs
Font Issues
- Provide a font manager when SVG contains text
- Ensure fonts are properly loaded with
useFonts
- Check font family names match SVG requirements
- Use
Group component for transformations on Web
- Prepare transforms beforehand or use explicit matrices
SVG Limitations
Not all SVG features are supported. Some advanced features may not render:
- Complex filters may not work
- Some CSS features are limited
- JavaScript in SVG is not supported
- External resources may not load
See Also