Skip to main content
Technical preview

Redraw is currently in technical preview, available to start-react-native.dev subscribers. API is unstable.

Installation

Redraw ships as three packages:

PackageScopeMinimum Requirements
redrawCore libraryWebGPU
react-redrawReact bindingsReact 18
react-native-redrawReact Native bindingsReact Native WebGPU 0.5.11

The React and React Native packages depend on the core, so installing one of them automatically pulls in redraw.

Installation

While Redraw is in technical preview, packages are distributed as .tgz tarballs through GitHub Releases.

Vendored tarball install

Every release ships .tgz tarballs that you install from a local path in your project.

1. Download the tarballs. Open the latest release and download the .tgz files for the packages you need.

2. Drop them into your project. Create a vendors/ folder at the root of your project and move the tarballs into it. Commit the folder so other contributors and CI get the same files:

your-project/
├── package.json
└── vendors/
├── redraw-1.2.3.tgz
└── react-redraw-1.2.3.tgz

3. Reference them in package.json.

{
"dependencies": {
"redraw": "file:./vendors/redraw-1.2.3.tgz",
"react-redraw": "file:./vendors/react-redraw-1.2.3.tgz"
}
}

Then run yarn install (or npm install).

4. Upgrading. Download the new tarballs, replace the files in vendors/, bump the filenames in package.json, run yarn install, and commit the updated vendors/ folder, lockfile, and package.json.

note

The file: protocol pins to a local path, so the lockfile re-hashes on every upgrade. This makes version bumps explicit, which is a good thing, but it means you cannot use semver ranges with this option.

TypeGPU

While optional, the TypeGPU bundler plugin will enable you to write arbitrary TypeScript functions that will be compiled and executed on the GPU. This is extremely useful for custom effects and materials. For instance, in the example below, we set the color based on the normalized arc length of the path (ctx.t, in [0, 1]).

const Color = fn(
(canvas, ctx) => {
"use gpu";
const a = parseColor("#3FCEBC");
const b = parseColor("#DE589F");
canvas.color = std.mix(a, b, ctx.t);
},
);

Bundler plugin

unplugin-typegpu transpiles "use gpu" JavaScript/TypeScript bodies into WGSL at build time. Without it, GPU functions ship to the browser as plain JS and won't execute on the device.

Install the dev dependency:

yarn add -D unplugin-typegpu

Then wire up the variant matching your bundler.

Vite

// vite.config.ts
import { defineConfig } from "vite";
import typeGPU from "unplugin-typegpu/vite";

export default defineConfig({
plugins: [typeGPU({})],
});

Babel (Expo / React Native / Metro)

// babel.config.js
module.exports = {
presets: ["babel-preset-expo"],
plugins: ["unplugin-typegpu/babel"],
};

Webpack

// webpack.config.js
const TypeGPU = require("unplugin-typegpu/webpack").default;

module.exports = {
plugins: [TypeGPU({})],
};

tsover (operator overloading)

TypeGPU's vector and matrix types support operator overloading (a + b, v * 2.0, etc.), a feature vanilla TypeScript does not type-check. Redraw and its examples are compiled with tsover, a TypeScript fork from Software Mansion that adds operator-overload type checking.

If your project authors GPU code that uses operator overloading on TypeGPU types, alias typescript to tsover in package.json:

{
"devDependencies": {
"typescript": "npm:tsover@^5.9.11"
}
}

If you stick to function-style math (std.mul(a, b), std.add(v, 2.0)), the standard typescript package is sufficient.

Troubleshooting

file: install resolves but imports fail at runtime. The tarballs only contain the built dist/ output. If you see Cannot find module 'redraw' at runtime, check that the tarball filename in package.json matches what's actually in vendors/.

GPU functions silently produce wrong output (or nothing). The TypeGPU bundler plugin probably isn't running. Confirm unplugin-typegpu is wired into your bundler and that "use gpu" directives appear inside fn() bodies you author.

tsc complains about operators on vec2f / vec3f / vec4f. You're using operator overloading without tsover. Either alias typescript to npm:tsover@^5.9.11 in package.json, or rewrite the offending code with explicit std.add / std.mul calls.