React Native WebGPU

Native APIs

Integrations with the native platforms

On Android and iOS, you will find platform differences from the Web. Where a platform forces a difference, we re-surface it rather than hide it.

The most substantial differences live on the Canvas API: namely the manual frame presentation, and transparency handling.

Threading model

react-native-webgpu can drive WebGPU from more than one JavaScript runtime: the main JS runtime, the UI thread, and dedicated worklet runtimes (createWorkletRuntime / runOnRuntime, or a Vision Camera frame processor). Running off the JS thread is powered by React Native Worklets; Reanimated is not required. This module also works well with Bundle Mode and lets you run complex Three.js scenes on the UI thread or dedicated worklet threads.

You can run WebGPU code on the main thread, on the Worklets UI thread, or on a dedicated worklet thread. The API is symmetric across all threads, so you can run your rendering loop wherever you want.

device.lost and uncapturederror

device.lost and uncapturederror are only delivered on the main JS runtime. This is usually fine because the GPU device is typically created on the main JS thread and then sent to the UI or a dedicated worklet thread. If you create the device outside the main JS thread, those events won't fire.

See Worklets for the full UI-thread integration guide. In a Worklet, call installWebGPU() to install the WebGPU API on that thread.

import { installWebGPU } from "react-native-webgpu";

const renderFrame = (device: GPUDevice, context: GPUCanvasContext) => {
  "worklet";
  installWebGPU();
  // GPUBufferUsage, GPUTextureUsage, etc. are now available on this thread
  const buffer = device.createBuffer({
    size,
    usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
  });
  // ... render and present on this thread ...
};

Loading images

This module provides a createImageBitmap function you can use with copyExternalImageToTexture. Resolve a bundled asset to a URI, fetch it, and decode the blob. In React Native createImageBitmap also accepts an ArrayBuffer as input.

const url = Image.resolveAssetSource(require("./assets/image.png")).uri;
const response = await fetch(url);
const imageBitmap = await createImageBitmap(await response.blob());

device.queue.copyExternalImageToTexture(
  { source: imageBitmap },
  { texture },
  [imageBitmap.width, imageBitmap.height],
);

See copyExternalImageToTexture on MDN.

Native textures

Beyond the standard API, react-native-webgpu exposes Dawn's native surface interop so you can sample camera and video frames with zero copies through the CPU:

  • importSharedTextureMemory imports a native pixel surface (an IOSurface-backed CVPixelBuffer on iOS, an AHardwareBuffer on Android) as a sampleable GPUTexture via device.importSharedTextureMemory(...).
  • importExternalTexture is the higher-level path: device.importExternalTexture(...) hands you a GPUExternalTexture with hardware YUV→RGB color conversion and lifecycle management, plus non-spec rotation and mirrored options for camera orientation.

Both build on a default-on capability. Feature-detect it before importing, since some Android drivers and emulators don't support it:

if (!device.features.has("rnwebgpu/native-texture" as GPUFeatureName)) {
  return; // rare: some Android drivers/emulators can't import native surfaces
}

See Vision Camera for an end-to-end example applying WGSL effects to live camera frames, and Native Extensions for the full API.

See also