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:
importSharedTextureMemoryimports a native pixel surface (anIOSurface-backedCVPixelBufferon iOS, anAHardwareBufferon Android) as a sampleableGPUTextureviadevice.importSharedTextureMemory(...).importExternalTextureis the higher-level path:device.importExternalTexture(...)hands you aGPUExternalTexturewith hardware YUV→RGB color conversion and lifecycle management, plus non-specrotationandmirroredoptions 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
- Canvas - the rendering surface and frame loop
- React APIs - hooks and the device provider
- Worklets - UI-thread rendering
- Native Extensions - native interop on
GPUDevice