shadertown

React shader components, typed per shader

One <ShaderCanvas /> renders any of the 77 shaders in the catalogue, and its params are typed against the shader you name. It mounts wherever React does — Next.js, Vite, Remix.

A component, not a canvas ritual

Hand-rolled WebGPU means requesting a device, configuring a surface, compiling a pipeline, and tearing all of it down when the component unmounts. ShaderCanvas is that ritual as a React animated background component: it draws while visible, pauses off screen, holds a still frame under prefers-reduced-motion, and cleans up after itself.

Typed against the shader you pick

Name shader="aurora" and params only accepts aurora's controls — a slider that does not exist is a compile error, not a silently ignored prop. Changing params never recompiles a pipeline, so wiring them straight to component state is fine.

Next.js without ceremony

The renderer is browser-only and knows it, so a Next.js animated background is one client component away: no dynamic import dance, no SSR guard. A fallback prop covers the browsers that still lack WebGPU. The React docs list every prop.

Hero.tsx
import { ShaderCanvas } from "shadertown/react";

export function Hero() {
  return (
    <div className="hero">
      <ShaderCanvas
        shader="aurora"
        params={{ speed: 0.4, vignette: 0.5 }}
        aria-hidden
      />
      <h1>Your headline, over a live shader.</h1>
    </div>
  );
}

Put a shader behind your next hero

Tune one in the catalogue first — the props you see in the URL are the props you pass the component.