Skip to main content

Headless

Thanks to its offscreen capabilities, React Native Skia can run on Node. This means that you can use the Skia API to draw things that can be encoded and saved as images. By default, drawings will be executed on the CPU but it is possible to also use GPU Acceleration.

Hello World

You will notice in the example below that the import URL looks different than the one used in React Native. There are two reasons for it. First, because Node programs don't rely on module bundlers such as Webpack, you will need to use the commonjs build of React Native Skia. Finally, we want to import the Skia APIs we need on Node without importing the one that rely on pure React Native APIs.

tsx
import { LoadSkiaWeb } from "@shopify/react-native-skia/lib/commonjs/web/LoadSkiaWeb";
import { Fill, makeOffscreenSurface, drawOffscreen, getSkiaExports } from "@shopify/react-native-skia/lib/commonjs/headless";
(async () => {
const width = 256;
const height = 256;
const r = size * 0.33;
await LoadSkiaWeb();
// Once that CanvasKit is loaded, you can access Skia via getSkiaExports()
// Alternatively you can do const {Skia} = require("@shopify/react-native-skia")
const {Skia} = getSkiaExports();
const surface = makeOffscreenSurface(width, height);
const image = drawOffscreen(surface,
<Group blendMode="multiply">
<Circle cx={r} cy={r} r={r} color="cyan" />
<Circle cx={size - r} cy={r} r={r} color="magenta" />
<Circle
cx={size/2}
cy={size - r}
r={r}
color="yellow"
/>
</Group>);
console.log(image.encodeToBase64());
// Cleaning up CanvasKit resources
image.dispose();
surface.dispose();
})();
tsx
import { LoadSkiaWeb } from "@shopify/react-native-skia/lib/commonjs/web/LoadSkiaWeb";
import { Fill, makeOffscreenSurface, drawOffscreen, getSkiaExports } from "@shopify/react-native-skia/lib/commonjs/headless";
(async () => {
const width = 256;
const height = 256;
const r = size * 0.33;
await LoadSkiaWeb();
// Once that CanvasKit is loaded, you can access Skia via getSkiaExports()
// Alternatively you can do const {Skia} = require("@shopify/react-native-skia")
const {Skia} = getSkiaExports();
const surface = makeOffscreenSurface(width, height);
const image = drawOffscreen(surface,
<Group blendMode="multiply">
<Circle cx={r} cy={r} r={r} color="cyan" />
<Circle cx={size - r} cy={r} r={r} color="magenta" />
<Circle
cx={size/2}
cy={size - r}
r={r}
color="yellow"
/>
</Group>);
console.log(image.encodeToBase64());
// Cleaning up CanvasKit resources
image.dispose();
surface.dispose();
})();

GPU Acceleration

React Native Skia relies on the OffscreenCanvas API to support GPU-Accelerated offscreen surfacs. This means, that to benefit from the GPU acceleration, you will need to provide a polyfill of the OffscreenCanvas API on Node. For example, here is an OffScreenCanvas polyfill implementation that relies on WebGL using headless-gl.