npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-webgpu

v0.1.3

Published

A [WebGPU](https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API) port for react native to provide direct access to Metal and Vulkan for iOS and Android via the WebGPU api.

Readme

react-native-webgpu

A WebGPU port for react native to provide direct access to Metal and Vulkan for iOS and Android via the WebGPU api.

Contents

Running the examples

The best way to learn WebGPU is to check out the examples. You can find instructions to run the examples here.

Getting started

  • Install packages
yarn add react-native-webgpu
  • Install pods
cd ios
pod install
cd ..
  • Import react-native-webgpu in your root index.js file so it can install on app startup
// src/index.js
import {install} from 'react-native-webgpu';

install();
  • Add to metro.config.js to support .wgsl files
// metro.config.js
const defaultConfig = getDefaultConfig(__dirname);
const webGpuConfig = require('react-native-webgpu/metro');
const config = {
  resolver: {
    sourceExts: [
      ...defaultConfig.resolver.sourceExts,
      ...webGpuConfig.resolver.sourceExts,
    ],
  },
  transformer: {
    babelTransformerPath: require.resolve('react-native-webgpu/wgsl-babel-transformer'),
  },
};
  • TypeScript only, add global types to tsconfig.json
{
  "include": [
    "node_modules/react-native-webgpu/lib/typescript/react-native-webgpu.d.ts"
  ]
}
  • Android only, make sure the minSdkVersion is >=27
// android/build.gradle
buildscript {
  ext {
    minSdkVersion = 27
  }
}

Android emulator ⚠️

The Android emulator does not support Vulkan unless your machine is capable of running it. It is recommended to develop using an Android device, but you can try a workaround if that's not available to you.

If you're using a Mac and you need to run your app on an emulator you can try these experimental apis.

1. Launch emulator with experimental Vulkan support

ANDROID_EMU_VK_ICD=moltenvk emulator "@My_AVD_Name"

2. Force the surface to choose Vulkan backend

  • Either set the backends prop:
<WebGpuView backends={Platform.OS === android ? Backends.Vulkan : Backends.All} />
  • Or set the default backends prop globally.
defaultBackends.current =
  Platform.OS === 'android' ? Backends.Vulkan : Backends.All;

Please note, it's not safe to assume that the emulated backend will be identical to a real one. Be sure to test fully on devices before releasing to production.

Converting a WebGPU sample

There are a few small changes you will need to make to get your project working. Below is a simple example taken from WebGPU Samples. It has TODO:s marking the places we need to change.

import triangleVertWGSL from '../../shaders/triangle.vert.wgsl';
import redFragWGSL from '../../shaders/red.frag.wgsl';
import { quitIfWebGPUNotAvailable } from '../util';

const canvas = document.querySelector('canvas') as HTMLCanvasElement; // TODO: Remove web api
const adapter = await navigator.gpu?.requestAdapter(); // TODO: Use the navigator from `react-native-webgpu` instead of `global`
const device = await adapter?.requestDevice();
quitIfWebGPUNotAvailable(adapter, device); // TODO: Remove since web gpu is always supported 🎉

const context = canvas.getContext('webgpu') as GPUCanvasContext; // TODO: Use the context from `react-native-webgpu`

const devicePixelRatio = window.devicePixelRatio; // TODO: Remove sizing as we use React to layout our views
canvas.width = canvas.clientWidth * devicePixelRatio;
canvas.height = canvas.clientHeight * devicePixelRatio;
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();

context.configure({
  device,
  format: presentationFormat,
  alphaMode: 'premultiplied',
});

const pipeline = device.createRenderPipeline({
  layout: 'auto',
  vertex: {
    // TODO: `entryPoint` must be specified in `react-native-webgpu`
    module: device.createShaderModule({
      code: triangleVertWGSL,
    }),
  },
  fragment: {
    // TODO: `entryPoint` must be specified in `react-native-webgpu`
    module: device.createShaderModule({
      code: redFragWGSL,
    }),
    targets: [
      {
        format: presentationFormat,
      },
    ],
  },
  primitive: {
    topology: 'triangle-list',
  },
});

function frame() {
  const commandEncoder = device.createCommandEncoder();
  const textureView = context.getCurrentTexture().createView();

  const renderPassDescriptor: GPURenderPassDescriptor = {
    colorAttachments: [
      {
        view: textureView,
        clearValue: [0, 0, 0, 1],
        loadOp: 'clear',
        storeOp: 'store',
      },
    ],
  };

  const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
  passEncoder.setPipeline(pipeline);
  passEncoder.draw(3);
  passEncoder.end();

  device.queue.submit([commandEncoder.finish()]);
  // TODO: We need to tell the surface to present itself onscreen
  requestAnimationFrame(frame);
}
// TODO: Use `requestAnimationFrame` from `react-native-webgpu` so it is called in sync with the screen refresh rate, and automatically cancels on unmount
requestAnimationFrame(frame);

Here is a working (TypeScript) example. It has FIXED: comments to show where the changes were made.

import React from 'react';
import { WebGpuView, type WebGpuViewProps } from 'react-native-webgpu';
import triangleVertWGSL from '../../shaders/triangle.vert.wgsl';
import redFragWGSL from '../../shaders/red.frag.wgsl';

export function HelloTriangle() {
  // FIXED: get context, navigator and requestAnimationFrame from `react-native-webgpu` callback
  const onCreateSurface: WebGpuViewProps['onCreateSurface'] = async ({context, navigator, requestAnimationFrame}) => {
    const adapter = await navigator.gpu.requestAdapter();
    const device = await adapter!.requestDevice();

    const presentationFormat = navigator.gpu.getPreferredCanvasFormat();

    context.configure({
      device,
      format: presentationFormat,
      alphaMode: "premultiplied",
    });

    const pipeline = device.createRenderPipeline({
      layout: 'auto',
      vertex: {
        // FIXED: The shader function in `triangleVertWGSL` is called `main` so that's our entry point
        entryPoint: 'main',
        module: device.createShaderModule({
          code: triangleVertWGSL,
        }),
      },
      fragment: {
        // FIXED: The shader function in `redFragWGSL` is also called `main` so that's our entry point
        entryPoint: 'main',
        module: device.createShaderModule({
          code: redFragWGSL,
        }),
        targets: [
          {
            format: presentationFormat,
          },
        ],
      },
      primitive: {
        topology: 'triangle-list',
      },
    });

    function frame() {
      // FIXED: `getCurrentTexture()` can return `null` in `react-native-webgpu`
      const framebuffer = context.getCurrentTexture();
      if (!framebuffer) {
        requestAnimationFrame(frame);
        return;
      }

      const commandEncoder = device.createCommandEncoder();
      const textureView = framebuffer.createView();

      const renderPassDescriptor: GPURenderPassDescriptor = {
        colorAttachments: [
          {
            view: textureView,
            clearValue: [0, 0, 0, 1],
            loadOp: 'clear',
            storeOp: 'store',
          },
        ],
      }

      const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
      passEncoder.setPipeline(pipeline);
      passEncoder.draw(3);
      passEncoder.end();

      device.queue.submit([commandEncoder.finish()]);
      // FIXED: Add context.presentSurface() to display the surface
      context.presentSurface();
      requestAnimationFrame(frame);
    }
    requestAnimationFrame(frame);
  };

  return <WebGpuView onCreateSurface={onCreateSurface} style={{flex: 1}} />;
}

Resizing WebGpuView

If you expect WebGpuView to change size, you need to call context.configure() whenever the size changes.

let previousWidth = context.width;
let previousHeight = context.height;
// ...

function frame() {
  if (context.width !== previousWidth || context.height !== previousHeight) {
    context.configure({device, format});
  }
  previousWidth = context.width;
  previousHeight = context.height;
  
  const framebuffer = context.getCurrentTexture(); // Now returns updated texture
  // ...
}

Animating the size

If you want to smoothly change the size of WebGpuView, set the pollSize prop to true. This only affects iOS and polls the surface size every frame to ensure it is correct. Setting this to true on Android has no effect because animations are supported without polling the size.

<WebGpuView onCreateSurface={onCreateSurface} pollSize />

Production use

Like any third party code you introduce into your app, ensure that you thoroughly test on your supported platforms.

Memory

Running loop-based, resource-heavy code in JavaScript environments can be challenging. The library is profiled for memory usage, but you will need to test your app to make sure you're not accidentally introducing memory leaks.

Xcode Instruments and Android Studio Profiler are strongly recommended for profiling your app before releasing it to production.

Supported react-native versions

The library is built and tested against 0.75 and 0.76. Other versions may work but are not supported.

| react-native-webgpu | react-native | Hermes | JSC | New architecture | Old architecture | |---------------------|--------------|--------|-----|------------------|------------------| | 0.1.1 | 0.75-0.76 | ✅ | ❌ | ✅ | ✅ | | 0.1.2 | 0.76-0.78 | ✅ | ❌ | ✅ | ✅ | | 0.1.3 | 0.77-0.78 | ✅ | ❌ | ✅ | ✅ |