Skip to main content
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

NameTypeDescription
svgSkSVGSVG image instance loaded with useSVG
xnumberOptional x coordinate of the SVG container
ynumberOptional y coordinate of the SVG container
widthnumberWidth when root SVG uses relative units
heightnumberHeight 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>
  );
};

Platform Differences

Web Platform

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>

Native Platforms

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>
  );
};

Performance Tips

  • 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

Transform Issues on Web

  • 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

Build docs developers (and LLMs) love