Shader starter kit

The Shader Starter Kit demonstrates how to integrate WebGL shaders with tldraw, creating dynamic backgrounds that respond to canvas interactions. It includes four complete examples and a reusable WebGLManager base class for building custom shader effects.


Try it yourself

To build with a shader starter kit, run this command in your terminal:

npm create tldraw@latest -- --template shader

Use Cases

The shader starter kit is perfect for building:

  • Immersive creative tools: Layer animated, touch-responsive backgrounds behind your drawing UI for design or storytelling apps.
  • Data-rich dashboards: Highlight state changes or live metrics using GPU-driven gradients and particle systems that react to editor data.
  • Games and interactive experiences: Combine tldraw shapes with shader-based effects to build puzzle overlays, interactive maps, or ambient scenes.
  • Live events and streaming overlays: Drive real-time graphics for broadcast overlays or virtual stages that react to presenter actions.
  • Educational demos: Teach graphics concepts with interactive examples that expose shader parameters through the config panel.

How it works

WebGLManager lifecycle

The reusable WebGLManager class (src/WebGLManager.ts) creates and manages a WebGL2 context that is synchronized with the tldraw canvas. It owns the render loop and exposes lifecycle hooks—onInitialize(), onUpdate(), onRender(), and onDispose()—so each shader manager can focus on its effect-specific logic while sharing viewport coordination, resolution control, and animation timing.

Config panel system

The config panel components (src/config-panel/) provide ready-made UI controls for editing shader uniforms. Each panel stores settings in reactive atoms and persists them to localStorage, so your shader parameters survive reloads without extra wiring.

The template ships with four complete demos that follow the same pattern of manager, renderer, config panel, and GLSL files:

  • Fluid simulation (src/fluid/) — Navier-Stokes-based flow that turns pointer movement into velocity splats. Includes an in-depth guide.
  • Rainbow (src/rainbow/) — Gradient animation that demonstrates time-based uniforms and color cycling.
  • Shadows (src/shadow/) — Raymarched shadow effect using signed distance fields derived from canvas geometry.
  • Minimal (src/minimal/) — Dark-mode-aware solid color shader that makes it easy to start your own effect, with a step-by-step walkthrough.

Switch between demos from the style panel inside the starter kit to see how different managers plug into the same infrastructure.

Fluid simulation

A real-time fluid simulation that creates dynamic flows from shape interactions. Based on Pavel Dobryakov's WebGL fluid implementation.

  • Navier-Stokes fluid dynamics
  • Shape movements create velocity-based splats
  • Configurable physics and visual effects

See: src/fluid/ | Documentation

Rainbow

An animated gradient shader demonstrating time-based effects and uniform management.

See: src/rainbow/

Shadows

Dynamic shadow casting from tldraw shapes using raymarching and signed distance fields.

See: src/shadow/

Minimal

A bare-bones template for starting new shader projects. Renders a solid color that adapts to dark mode.

See: src/minimal/ | Documentation


Customization

Start from the minimal template

Copy the minimal shader to create a new effect:

cp -r src/minimal src/my-shader

Then update:

  • config.ts — Define uniforms and UI controls for your shader.
  • fragment.glsl / vertex.glsl — Implement rendering logic.
  • MyShaderManager.ts — Extend WebGLManager and coordinate buffers, uniforms, and lifecycle hooks.
  • MyRenderer.tsx — Mount the manager from React and handle cleanup.
  • MyConfigPanel.tsx — Customize the controls exposed to users.

Finally, register the new manager in src/App.tsx.

Extend WebGLManager hooks

Each manager can override lifecycle hooks to add render targets, resize behavior, or post-processing passes. Use onInitialize() to set up buffers, textures, and framebuffers; onUpdate() for per-frame uniform updates (such as time, resolution, or editor-driven state); and onRender() to issue draw calls. The base class also exposes helpers for handling pixel density and canvas resizes.

Integrate with tldraw data

Every manager receives the live tldraw editor instance, which lets you:

  • Access shapes with editor.getCurrentPageShapes().
  • Subscribe to document changes through editor.store.listen().
  • Read the current camera via editor.getCamera().
  • Convert coordinates with editor.pageToViewport().
  • Track pointer data from editor.inputs.currentPagePoint.

See src/fluid/FluidManager.ts for a full example of mixing editor state with GPU simulation.

Resources


Further reading

  • Multiplayer Starter Kit: Use a tldraw multiplayer sync starter kit to build multi-user shader environments.

  • Shape Utilities: Learn how to create custom shapes and extend tldraw's shape system with advanced geometry, rendering, and interaction patterns.

  • Editor State Management: Learn how to work with tldraw's reactive state system, editor lifecycle, and event handling for complex canvas applications.


Building with this starter kit?

If you build something great, please share it with us in our #show-and-tell channel on Discord. We want to see what you've built!

Prev
Multiplayer starter kit
Next
Translations
Is this page helpful?