TypeGPU
Write type-safe WebGPU shaders in TypeScript with TypeGPU
TypeGPU is a type-safe WebGPU toolkit from Software Mansion. Data structures declared with d.struct handle WGSL alignment and padding for you, and shaders are plain TypeScript functions marked with the "use gpu" directive - compiled to WGSL at build time by unplugin-typegpu.
Because React Native WebGPU is symmetric to the Web API, TypeGPU runs on it unmodified. Its React bindings, @typegpu/react, even ship a dedicated React Native entry point that imports react-native-webgpu directly - so hooks like useRoot() and useConfigureContext() work out of the box with the <Canvas> component.
1. Installation
npm i typegpu @typegpu/react
npm i -D unplugin-typegpuRegister the Babel plugin so "use gpu" functions are transpiled to WGSL at build time:
// babel.config.js
module.exports = {
presets: ["module:@react-native/babel-preset"],
plugins: ["unplugin-typegpu/babel"],
};Babel plugin required
Without unplugin-typegpu/babel, functions marked "use gpu" reach the runtime as plain JavaScript and TypeGPU cannot generate WGSL from them.
2. Render pipeline
A complete component drawing a full-screen gradient, with React state mirrored on the GPU as a uniform:
import { , } from "react";
import { } from "react-native-webgpu";
import { common, d, std } from "typegpu";
import {
,
,
,
,
} from "@typegpu/react";
export function () {
const = ();
const [] = (4);
const [] = (4);
// Mirroring React state on the GPU as a uniform
const = (d., d.(, ));
const = (() => {
// Defining a full-screen shader in TypeScript
return .({
: common.,
: ({ }) => {
"use gpu";
const = std.(. * d.(..)) / d.(..);
const = std.(. * d.(..)) / d.(..);
return d.(, , 0.5, 1.0);
},
});
}, [, ]);
const { , } = ();
(() => {
const = .;
if (!) return;
// Drawing to the canvas each frame
.({ : }).(3);
.?.();
});
return < ={} ={{ : 1 }} />;
}The React Native specific glue is minimal:
useRoot()creates aTgpuRootfrom the globalnavigator.gpu, whichreact-native-webgpuinstalls at import time (Installation) - no provider or device plumbing needed.useConfigureContext()returns arefyou pass to<Canvas>and actxRefholding the configuredGPUCanvasContext.ctx.present?.()flushes the frame to the screen - required on React Native (frame presentation), a no-op guard on the Web.
3. Compute pipelines
Compute shaders are TypeScript functions too. Buffers, uniforms, and bind groups come from hooks, and createGuardedComputePipeline dispatches one thread per element with the bounds check generated for you:
import { } from "react";
import , { d } from "typegpu";
import { , , } from "@typegpu/react";
const = d.({
: d.,
: d.,
});
const = d.();
const = .({
: { : , : "mutable" },
});
function (: number) {
"use gpu";
const = (..[]);
. = ..(.);
..[] = ();
}
const = 1000;
export function () {
const = ();
const = (()).("storage");
const = (, { });
const = (
() => .(),
[],
);
return () => {
.().();
};
}Chain it with a render pipeline inside useFrame to simulate and draw in the same frame.
Examples
The example app contains three TypeGPU demos you can run on device:
- GradientTiles - the render pipeline above, with buttons driving the uniform via React state.
- ComputeBoids - a flocking simulation combining a compute pipeline with an instanced render pipeline, double-buffered storage buffers, and tweakable physics parameters.
- MNISTInference - hand-written digit recognition running a neural network in compute shaders, with React Native Skia for the drawing surface.