{"id":14386716,"url":"https://github.com/wcandillon/react-native-webgpu","last_synced_at":"2025-05-15T00:07:26.745Z","repository":{"id":252969324,"uuid":"816390466","full_name":"wcandillon/react-native-webgpu","owner":"wcandillon","description":"React Native implementation of WebGPU using Dawn","archived":false,"fork":false,"pushed_at":"2025-05-10T16:59:20.000Z","size":27666,"stargazers_count":650,"open_issues_count":22,"forks_count":27,"subscribers_count":18,"default_branch":"main","last_synced_at":"2025-05-10T17:27:50.121Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wcandillon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-06-17T16:44:42.000Z","updated_at":"2025-05-10T16:59:24.000Z","dependencies_parsed_at":"2025-04-14T14:53:30.844Z","dependency_job_id":"530dcdc2-f3d1-4160-8fb9-d0808273b202","html_url":"https://github.com/wcandillon/react-native-webgpu","commit_stats":null,"previous_names":["wcandillon/react-native-webgpu"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wcandillon%2Freact-native-webgpu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wcandillon%2Freact-native-webgpu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wcandillon%2Freact-native-webgpu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wcandillon%2Freact-native-webgpu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wcandillon","download_url":"https://codeload.github.com/wcandillon/react-native-webgpu/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254249197,"owners_count":22039029,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-28T20:00:46.533Z","updated_at":"2025-05-15T00:07:21.736Z","avatar_url":"https://github.com/wcandillon.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","Libraries"],"sub_categories":["Safari"],"readme":"# React Native WebGPU\n\nReact Native implementation of WebGPU using [Dawn](https://dawn.googlesource.com/dawn).  \nThis is currently a technical preview for early adopters.  \n\n## Installation\n\nPlease note that the package name is `react-native-wgpu`.\n\n```\nnpm install react-native-wgpu\n```\n\nBelow are some examples from the [example app](/apps/example/).\n\nhttps://github.com/user-attachments/assets/116a41b2-2cf8-49f1-9f16-a5c83637c198\n\nStarting from `r168`, Three.js runs out of the box with React Native WebGPU.\nYou need to have a slight modification of [the metro config](/apps/example/metro.config.js) to resolve Three.js to the WebGPU build.\nWe also support [three-fiber](/apps/example/src/ThreeJS/Fiber.tsx).\nFor model loading, we also need [the following polyfill](/apps/example/src/App.tsx#29).\n\nhttps://github.com/user-attachments/assets/5b49ef63-0a3c-4679-aeb5-e4b4dddfcc1d\n\nWe also provide prebuilt binaries for visionOS and macOS.\n\nhttps://github.com/user-attachments/assets/2d5c618e-5b15-4cef-8558-d4ddf8c70667\n\n## Usage\n\nCurrently we recommend to use the `useCanvasEffect` to access the WebGPU context.\n\n```tsx\nimport React from \"react\";\nimport { StyleSheet, View, PixelRatio } from \"react-native\";\nimport { Canvas, useCanvasEffect } from \"react-native-wgpu\";\n\nimport { redFragWGSL, triangleVertWGSL } from \"./triangle\";\n\nexport function HelloTriangle() {\n  const ref = useCanvasEffect(async () =\u003e {\n    const adapter = await navigator.gpu.requestAdapter();\n    if (!adapter) {\n      throw new Error(\"No adapter\");\n    }\n    const device = await adapter.requestDevice();\n    const presentationFormat = navigator.gpu.getPreferredCanvasFormat();\n\n    const context = ref.current!.getContext(\"webgpu\")!;\n    const canvas = context.canvas as HTMLCanvasElement;\n    canvas.width = canvas.clientWidth * PixelRatio.get();\n    canvas.height = canvas.clientHeight * PixelRatio.get();\n\n    if (!context) {\n      throw new Error(\"No context\");\n    }\n\n    context.configure({\n      device,\n      format: presentationFormat,\n      alphaMode: \"opaque\",\n    });\n\n    const pipeline = device.createRenderPipeline({\n      layout: \"auto\",\n      vertex: {\n        module: device.createShaderModule({\n          code: triangleVertWGSL,\n        }),\n        entryPoint: \"main\",\n      },\n      fragment: {\n        module: device.createShaderModule({\n          code: redFragWGSL,\n        }),\n        entryPoint: \"main\",\n        targets: [\n          {\n            format: presentationFormat,\n          },\n        ],\n      },\n      primitive: {\n        topology: \"triangle-list\",\n      },\n    });\n\n    const commandEncoder = device.createCommandEncoder();\n\n    const textureView = context.getCurrentTexture().createView();\n\n    const renderPassDescriptor: GPURenderPassDescriptor = {\n      colorAttachments: [\n        {\n          view: textureView,\n          clearValue: [0, 0, 0, 1],\n          loadOp: \"clear\",\n          storeOp: \"store\",\n        },\n      ],\n    };\n\n    const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);\n    passEncoder.setPipeline(pipeline);\n    passEncoder.draw(3);\n    passEncoder.end();\n\n    device.queue.submit([commandEncoder.finish()]);\n\n    context.present();\n  });\n\n  return (\n    \u003cView style={style.container}\u003e\n      \u003cCanvas ref={ref} style={style.webgpu} /\u003e\n    \u003c/View\u003e\n  );\n}\n\nconst style = StyleSheet.create({\n  container: {\n    flex: 1,\n  },\n  webgpu: {\n    flex: 1,\n  },\n});\n```\n\n## Example App\n\nTo run the example app you first need to [build Dawn or download the prebuilt binaries](#building-dawn).\n\nFrom there you will be able to run the example app properly.\n\n## Similarities and Differences with the Web\n\nThe API has been designed to be completely symmetric with the Web.  \nFor instance, you can access the WebGPU context synchronously, as well as the canvas size.  \nPixel density and canvas resizing are handled exactly like on the Web as well.\n\n```tsx\n// The default canvas size is not scaled to the device pixel ratio\n// When resizing the canvas, the clientWidth and clientHeight are updated automatically\n// This behaviour is symmetric to the Web\nconst ctx = canvas.current.getContext(\"webgpu\")!;\nctx.canvas.width = ctx.canvas.clientWidth * PixelRatio.get();\nctx.canvas.height = ctx.canvas.clientHeight * PixelRatio.get();\n```\n\n### Frame Scheduling\n\nIn React Native, we want to keep frame presentation as a manual operation as we plan to provide more advanced rendering options that are React Native specific.  \nThis means that when you are ready to present a frame, you need to call `present` on the context.\n\n```tsx\n// draw\n// submit to the queue\ndevice.queue.submit([commandEncoder.finish()]);\n// This method is React Native only\ncontext.present();\n```\n\n### External Textures\n\nThis module provides a `createImageBitmap` function that you can use in `copyExternalImageToTexture`.\n\n```tsx\nconst url = Image.resolveAssetSource(require(\"./assets/image.png\")).uri;\nconst response = await fetch(url);\nconst imageBitmap = await createImageBitmap(await response.blob());\n\nconst texture = device.createTexture({\n  size: [imageBitmap.width, imageBitmap.height, 1],\n  format: \"rgba8unorm\",\n  usage:\n    GPUTextureUsage.TEXTURE_BINDING |\n    GPUTextureUsage.COPY_DST |\n    GPUTextureUsage.RENDER_ATTACHMENT,\n});\ndevice.queue.copyExternalImageToTexture(\n  { source: imageBitmap },\n  { texture },\n  [imageBitmap.width, imageBitmap.height],\n);\n```\n\n## Troubleshooting\n\n### iOS\n\nTo run the React Native WebGPU project on the iOS simulator, you need to disable the Metal validation API.  \nIn \"Edit Scheme,\" uncheck \"Metal Validation.\"\n\n\u003cimg width=\"1052\" alt=\"Uncheck 'Metal Validation'\" src=\"https://github.com/user-attachments/assets/2676e5cc-e351-4a97-bdc8-22cbd7df2ef2\"\u003e\n\n## Library Development\n\nMake sure to check out the submodules:\n\n```\ngit submodule update --init\n```\n\nMake sure you have all the tools required for building the Skia libraries (Android Studio, XCode, Ninja, CMake, Android NDK/build tools).\n\n### Building Dawn\n\n```sh\nyarn\ncd packages/webgpu\nyarn build-dawn\n```\n\nYou can also filter the platforms to build, for instance to skip the macOS and visionOS build:\n```sh\nyarn build-dawn --exclude=xros,xrsimulator,macosx\n```\n\nAlternatively if you want to build for a specific platform only, you can use `includeOnly`.\n```sh\nyarn build-dawn --includeOnly=xros,xrsimulator\n```\n\n### Downloading Dawn\n\nThere is an alternative way which is to download the prebuilt binaries from GitHub.\nYou need to have the [Github CLI](https://cli.github.com/) installed:\n\n```sh\n$ yarn\n$ cd packages/webgpu\n$ yarn download-artifacts\n$ yarn copy-artifacts\n```\n\nAlternatively you can also download the prebuilt binaries [here](https://github.com/wcandillon/react-native-webgpu/actions/workflows/build-dawn.yml).\n\n### Upgrading\n\n1. `git submodule update --remote`\n2. `yarn clean-dawn`\n3. `yarn build-dawn`\n\n### Codegen\n\n* `cd packages/webgpu \u0026\u0026 yarn codegen`\n\n### Testing\n\nIn the `package` folder, to run the test against Chrome for reference:\n\n```\nyarn test:ref\n```\n\nTo run the e2e test, open the example app on the e2e screen.  \nBy default, it will try to connect to a localhost test server.  \nIf you want to run the test suite on a physical device, you can modify the address [here](/apps/example/src/useClient.ts#L4).\n\n```\nyarn test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwcandillon%2Freact-native-webgpu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwcandillon%2Freact-native-webgpu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwcandillon%2Freact-native-webgpu/lists"}