The shader layer, not the component layer
People ask how vshaders relates to effect component libraries, most often Canvas UI. Short answer: different layers of the stack, and they can coexist. This page explains the difference without a scoreboard.
What component libraries do well
Canvas UI, by the author of React Bits, ships finished, polished effect components over WebGL in six framework flavors, distributed through the shadcn registry so the source lands in your project. When you want a beautiful effect as a component, drop it in and move on. That model works, and its popularity proves people want to own the code they ship.
What vshaders does instead
vshaders distributes the layer underneath: the shader itself. On vgpu, WGSL files import and export like TypeScript modules, resolved from npm through each package's exports map. An effect here is a composition: an entry shader you own, plus the modules it imports as versioned dependencies.
That structure is the whole point. In WebGL libraries the shader inside a component is a GLSL string, because GLSL has no module system; sharing code means copying it, and customizing means editing a blob. WGSL modules through vgpu give the shader layer what JavaScript has had for a decade: imports, versioning, dead-code elimination, and typed reflection.
The differences, factually
| Canvas UI | vshaders | |
|---|---|---|
| Rendering | WebGL, via three.js | WebGPU, via vgpu |
| Unit of reuse | A finished component | A WGSL module, or a composition of them |
| Shader source | GLSL inside the component | WGSL modules imported from npm |
| Customization | Edit the component's source | Tune uniforms, edit the entry shader, or swap an imported module |
| Uniform types | TypeScript props | TypeScript props plus WGSL reflection |
| Frameworks | React, Solid, Preact, Vue, Svelte, vanilla | React and vanilla today |
| License | MIT with Commons Clause | MIT |
Some of those rows favor them: six framework flavors is real work and real reach. The rows about structure are the ones vshaders exists for.
What low-level control buys you
When an effect is a composition instead of a blob, every level is yours to touch. Change a color: that's a uniform. Change the gradient's character: swap simplex2d for fbmPerlin2d in one import line. Change the shape language: the SDF primitives are right there, documented, with the same math you'd write by hand. Shared primitives are versioned dependencies, so a fix in @vshaders/sdf reaches every effect that imports it. And because vgpu validates the composed shader against a real device, the registry can check every effect in CI before it reaches you.
The same structure is what makes effects legible to coding agents. An agent that pulls an effect gets the composition: the entry shader, its typed uniforms, and the import graph, not an opaque component. It can tune, swap, and verify with the same tools a person uses.
Where this is going
Every effect in the registry will open in an editor that shows the primitives it imports and exposes its uniforms as controls, derived automatically from vgpu's reflection. The state you dial in becomes part of the effect's id, and vshaders add <id> copies the whole composition into your project with your values as the defaults. Prefer raw materials? The packages are plain npm installs, and the shadcn CLI path works too.
If a component library ever wants to build on these modules, that would be a good outcome. Different layers compose; that's the thesis.