Open-source project
software-mansion/TypeGPU avatar
software-mansion/TypeGPU

TypeGPU: Writing WebGPU Shaders in TypeScript

A modular and open-ended toolkit for WebGPU, with advanced type inference and the ability to write shaders in TypeScript

3,242 stars129 forksTypeScriptMIT

At a glance

What is it?
TypeGPU is a modular TypeScript toolkit for WebGPU that mirrors WGSL syntax, infers types from your buffers and shaders, and lets you eject into vanilla WebGPU at any point. It is aimed at engineers who want type safety without giving up the underlying API.
Who is it for?
Adopt TypeGPU if you are building a WebGPU app or library in TypeScript and want type inference over your buffers and shader entry points, or if you need an interoperability layer between two WebGPU libraries that pass typed data. Do not adopt it if you are satisfied with hand-written WGSL and manual bind group layouts, or if your target runtime has no WebGPU.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The gap TypeGPU fills between TypeScript and WGSL

Writing WebGPU code by hand means writing WGSL in a string, then describing the same data layout a second time in TypeScript when you create a GPUBuffer and a bind group layout. The two descriptions drift. A struct field changes in the shader and the buffer size silently stays wrong until something renders incorrectly.

TypeGPU attacks that duplication. Its README describes it as "a modular and open-ended toolkit for WebGPU, with advanced type inference and the ability to write shaders in TypeScript." The audience is narrow and specific: TypeScript developers already committed to WebGPU who want the compiler to check their data layouts and shader entry points, and library authors who need to hand typed GPU buffers to other libraries without copying data back to JavaScript.

The repository package.json describes the project as "a thin layer between JS and WebGPU/WGSL that improves development experience and allows for faster iteration." Thin is the operative word. This is not a renderer, a scene graph or a game engine. It does not decide your frame loop.

How GPU functions, schemas and root work together

The central mechanism is the 'use gpu' directive. A function marked with it can be called three ways, and the README shows all three in one snippet. Called from JavaScript it returns a typed value. Passed to tgpu.resolve it becomes a WGSL string. Given to a guarded compute pipeline and dispatched, it runs on the GPU and the WGSL is generated underneath.

That single source of truth is the whole design. The same neighborhood function is a plain TypeScript call, a shader source generator, and a dispatchable kernel.

Data layout comes from schemas. The README defines one as a function returning a schema, then infers a type from it with ReturnType:

ts
const HeightMap = (width: number, height: number) =>
  d.arrayOf(d.arrayOf(d.f32, height), width);

type HeightMap = ReturnType<typeof HeightMap>;

Buffers created from that schema carry the inferred type. The README's library example shows a TgpuBuffer<WgslArray<WgslArray<F32>>> that is rejected when passed to a function expecting TgpuBuffer<WgslArray<F32>>, and accepted by the correctly typed array2d call. That is a compile-time check on a GPU memory shape, which is the part hand-written WebGPU cannot give you.

A TgpuRoot ties allocation together. The README calls it "common root for allocating resources" and shows it created with await tgpu.init(). Buffers come from root.createBuffer(...), and root.unwrap(buffer) returns the underlying GPUBuffer so you can keep using raw WebGPU calls on the same memory. The README notes that "any changes to it will be visible in both," which is what makes partial adoption viable rather than all-or-nothing.

Installing TypeGPU and running a first compute dispatch

The README points to the getting-started guide at docs.swmansion.com/TypeGPU/getting-started rather than listing install steps. The npm package name used in the README's own examples is typegpu, and the repository is a pnpm workspace (pnpm-workspace.yaml, pnpm-lock.yaml), so pnpm is the package manager the project itself uses. Add the package to your project:

bash
pnpm add typegpu

Then initialize a root and dispatch a kernel. This is the third usage from the README's opening snippet, with the import added because the README shows it in its library section:

ts
import { tgpu } from 'typegpu';
import { d } from 'typegpu';

const neighborhood = (a: number, r: number) => {
  'use gpu';
  return d.vec2f(a - r, a + r);
};

const main = () => {
  'use gpu';
  return neighborhood(1.1, 0.5);
};

const root = await tgpu.init();
root.createGuardedComputePipeline(main).dispatchThreads();

What you should see is a compute dispatch with no WGSL written by hand. If you want to inspect the generated shader before wiring it into a pipeline, call tgpu.resolve([main]) instead, which the README types as returning a string. Note the module-level await on tgpu.init(); the README uses it in a top-level context, so in a bundler that does not support top-level await you would need to move it inside an async function.

Where TypeGPU stops being the right tool

TypeGPU does not remove WebGPU from the picture. Every example in the README assumes a working WebGPU implementation, and the toolkit mirrors WGSL syntax rather than replacing it. If your target runtime lacks WebGPU, nothing here helps you.

The README also does not document rollback or migration paths away from the typed layer. The claim is that you can "granularly eject into vanilla WebGPU at any point," and root.unwrap(buffer) is the concrete escape hatch for buffers, but the README does not show the equivalent for pipelines, bind group layouts or command encoding. Treat the ejection story as partially documented.

There is a second cost that the README does not discuss: the 'use gpu' directive depends on a transform. The repository has a test script named transform-overloads and a packages/typegpu-cli directory with templates, which indicates a build-time step exists in the toolchain. A project that cannot add a transform to its build, or that compiles shaders in an environment where that step does not run, will not get the same behaviour.

Finally, this is a young API. The releases show v0.12.5 on 2026-09-07, with v0.12.4 and v0.12.3 earlier that same quarter. Pre-1.0 version numbers mean minor releases can change behaviour, and the repository carries a patches/ directory, which suggests the maintainers occasionally need to patch dependencies.

TypeGPU against three.js and raw WebGPU

The comparison people search for is three.js, and the difference is not performance, it is layer. three.js is a scene graph and renderer: cameras, materials, meshes, lights. TypeGPU has none of that. It sits below the renderer, at the level of buffers, shader entry points and compute dispatches. If you want a 3D scene with lighting, three.js already solves a problem TypeGPU does not address. If you want a typed compute kernel that another library can consume, three.js is the wrong shape of tool.

Against raw WebGPU the difference is the type layer. With raw WebGPU you write WGSL as a string and describe layouts manually. With TypeGPU you write the function in TypeScript and the WGSL is generated by tgpu.resolve. The README frames the trade explicitly: learning TypeGPU "helps to learn WebGPU itself, with fewer frustrations," and lock-in is addressed by ejecting into vanilla WebGPU. The cost is an extra dependency and a build transform in exchange for compile-time checking of buffer shapes.

The more interesting comparison is not a competing library at all. The README positions TypeGPU as "an interoperability layer between use-case specific libraries," with a worked example of a procedural generation library (@xyz/gen) handing a typed height map buffer to a plotting library (@abc/plot). Without a shared type vocabulary, that handoff either goes through untyped WebGPU or copies data back to the CPU. That is a problem neither three.js nor raw WebGPU is designed to solve.

Maintenance, licensing and the cost of keeping up

The repository is not archived, and the last push was on 2026-09-23. Releases have been frequent: v0.12.5 on 2026-09-07, v0.12.4 on 2026-08-28, v0.12.3 on 2026-08-22. That cadence is a maintenance signal, but it also means the surface you depend on moves. The v0.12.5 release bundles three packages at different versions (typegpu v0.12.5, @typegpu/gl v0.12.4, @typegpu/cli v0.12.3), so upgrades are not a single version bump if you use more than the core package.

The root package.json is private and version 0.0.0, so there is no monorepo-level version to track. You pin the individual packages. The test script is a chain that includes test:types, test:style, test:unit-and-attest, test:built-unit-and-attest and test:circular-deps, which tells you the maintainers run type-level tests and check for circular dependencies in the published entry points. That is a stronger safety net than many pre-1.0 projects carry, but it is their net, not yours.

The licence is MIT, declared in both package.json and the LICENSE file. MIT permits commercial and closed-source use and requires preserving the copyright notice and licence text. That is the extent of what can be said here; the terms are short and worth reading directly rather than taking a summary.

Editorial conclusion

Adopt TypeGPU if you are building a WebGPU app or library in TypeScript and want type inference over your buffers and shader entry points, or if you need an interoperability layer between two WebGPU libraries that pass typed data. Do not adopt it if you are satisfied with hand-written WGSL and manual bind group layouts, or if your target runtime has no WebGPU. Before committing, verify your browser or runtime exposes WebGPU, check that the tgpu.resolve output matches what your render pipeline expects, and confirm that the packages you need are published under the typegpu and @typegpu scopes at the versions you intend to pin.

Frequently asked questions

What is TypeGPU?

It is a modular toolkit for WebGPU that lets you write shaders in TypeScript with advanced type inference. The README describes it as a thin layer between JS and WebGPU/WGSL, and you can eject into vanilla WebGPU at any point.

How does TypeGPU compare to three.js?

They operate at different layers. three.js is a scene graph and renderer, while TypeGPU works at the level of buffers, shader entry points and compute dispatches, and the README positions it as an interoperability layer between use-case specific libraries.

How do I install TypeGPU?

The README points to the getting-started guide at docs.swmansion.com/TypeGPU/getting-started rather than listing install steps. The package name used in the README's examples is typegpu, and the repository itself is a pnpm workspace.

Can I still use raw WebGPU with TypeGPU?

Yes. The README states that you can granularly eject into vanilla WebGPU at any point, and root.unwrap(buffer) returns the underlying GPUBuffer so that changes are visible in both the typed object and the raw resource.

What does the 'use gpu' directive do in TypeGPU?

A function marked with 'use gpu' can be called from JavaScript, passed to tgpu.resolve to generate a WGSL string, or dispatched on the GPU through a guarded compute pipeline. The README shows all three usages on the same function.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. software-mansion/TypeGPU on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/software-mansion-typegpu.svg)](https://hysenlabs.com/projects/software-mansion-typegpu)