Skip to main content

Migrating to v3

React Native Skia v3 renders with Skia Graphite on iOS, macOS, and Android. Graphite is Skia's new GPU backend. In React Native Skia it runs on Dawn, Google's WebGPU implementation, which uses Metal on Apple platforms and Vulkan on Android.

Staying on v2

v2 is still maintained. It renders with OpenGL ES on Android and has lower version requirements: it runs on Android devices below API level 26 or without Vulkan, and it supports tvOS, Android TV, Mac Catalyst, and Expo Go. If you need any of these, stay on v2 (yarn add react-native-skia@2) and use the v2 documentation.

The drawing API is the same as in v2: components, hooks, shaders, and the imperative Skia API all work as before. What changes is the package name, the platform requirements, and a few Canvas props. Most apps migrate in three steps:

  1. Rename the package
  2. Check the platform requirements
  3. Update the Canvas props

1. Rename the package​

The package is now published as react-native-skia. @shopify/react-native-skia stops at version 2.14. If your project already depends on react-native-skia (2.15), skip to the next step.

yarn remove @shopify/react-native-skia
yarn add react-native-skia

Then update the imports, including the deep imports used on Web and in headless mode:

- import { Canvas, Circle } from "@shopify/react-native-skia";
- import { LoadSkiaWeb } from "@shopify/react-native-skia/lib/module/web";
+ import { Canvas, Circle } from "react-native-skia";
+ import { LoadSkiaWeb } from "react-native-skia/lib/module/web";

The following command rewrites every import of a git repository in one go:

git grep -l "@shopify/react-native-skia" -- '*.ts' '*.tsx' '*.js' '*.jsx' \
| xargs perl -pi -e 's#\@shopify/react-native-skia#react-native-skia#g'

The Jest configuration references the package by name as well:

// jest.config.js
module.exports = {
- testEnvironment: "@shopify/react-native-skia/jestEnv.js",
- setupFilesAfterEnv: ["@shopify/react-native-skia/jestSetup.js"],
+ testEnvironment: "react-native-skia/jestEnv.js",
+ setupFilesAfterEnv: ["react-native-skia/jestSetup.js"],
transformIgnorePatterns: [
- "node_modules/(?!(react-native|react-native.*|@react-native.*|@?react-navigation.*|@shopify/react-native-skia)/)"
+ "node_modules/(?!(react-native|react-native.*|@react-native.*|@?react-navigation.*|react-native-skia)/)"
],
};
warning

Do not install @shopify/react-native-skia and react-native-skia side by side: both ship the same native module. A library that imports from @shopify/react-native-skia needs a release that targets react-native-skia before you can use it with v3.

2. Check the platform requirements​

Android​

v3 requires Android API level 26 or above and renders with Vulkan instead of OpenGL ES. React Native projects default to a lower minSdkVersion, so raise it in android/build.gradle:

buildscript {
ext {
minSdkVersion = 26
}
}

iOS and macOS​

The minimum deployment target is iOS 15.1. Run pod install again after upgrading: the Skia binaries come from new npm packages (react-native-skia-graphite-apple-ios and react-native-skia-graphite-apple-macos), which also ship Dawn.

Expo​

Expo Go bundles the native code of v2, so v3 needs a development build:

npx expo install react-native-skia expo-build-properties
npx expo run:ios
npx expo run:android

Use expo-build-properties to raise the Android minSdkVersion:

{
"expo": {
"plugins": [
["expo-build-properties", { "android": { "minSdkVersion": 26 } }]
]
}
}

TV and Mac Catalyst​

tvOS, Android TV, and Mac Catalyst are not available with Graphite. These platforms remain supported on v2.

React Native WebGPU​

If your app also uses react-native-webgpu, both packages now link the same copy of Dawn. The native build fails with a Dawn version mismatch error if they were built against different Dawn releases: upgrade both packages together. In exchange, Skia and WebGPU can now share a device and textures without any copy (see WebGPU).

3. Update the Canvas props​

Three props of <Canvas> were removed:

PropReplacement
debugNone, remove the prop.
colorSpaceNone, remove the prop. The canvas picks its color space itself: Display P3 on Apple devices with a wide color gamut display (the default of v2), sRGB everywhere else.
androidWarmupNone, remove the prop. To control how the canvas is composited on Android, see the Android rendering options.

The NativeSkiaViewProps type was removed as well.

What is new​

Rendering off the JS and UI threads​

In v2, <Canvas> drew its frames on the UI thread. In v3, the scene is recorded once per React commit, and a dedicated native thread pool replays it into a Graphite frame whenever its content changes. The UI thread only applies the animated values, it no longer draws. Nothing changes in your code: see how frames are produced.

Textures can be used from any thread​

With Ganesh, a GPU texture belonged to the Skia context of the thread that created it, which is why v2 created textures on the UI thread. With Graphite, GPU-backed images are shared: an image created on the JS thread can be drawn by any canvas and from any worklet runtime. The texture hooks work as before.

SkiaGraphiteView​

SkiaGraphiteView is a view that you drive frame by frame from any JavaScript runtime: the JS thread, the Reanimated UI runtime, or a dedicated worklet runtime.

WebGPU interop​

With react-native-webgpu installed, Skia and WebGPU share the same GPU device. You can draw a WebGPU texture in a Skia canvas, or draw with Skia into a texture that WebGPU samples, without any copy. This also works with three.js: see WebGPU.

High bit depth on Android​

The highBitDepth prop is now supported on Android, where it renders into a 10-bit surface.

Troubleshooting​

The Android build fails after upgrading. Check that minSdkVersion is 26 or above, then clean the native build (cd android && ./gradlew clean).

The iOS build fails after upgrading. Run pod install again so CocoaPods picks up the new binary packages.

The build reports a Dawn version mismatch. react-native-skia and react-native-webgpu were built against different Dawn releases. Upgrade both to their latest versions.

The app does not run in Expo Go. Expo Go ships the native code of v2. Use a development build.

Screenshot tests report differences. Graphite is a different renderer than Ganesh, and its output can differ slightly. Review the differences and update your reference images.

If you run into an issue that is not listed here, please open an issue.