tutorial · 8 min read · April 18, 2026

How to Add WebGL Shader Backgrounds to Your Astro Site

WebGL shader backgrounds have become the definitive visual signature of premium web experiences — you see them on Stripe, Linear, and every Awwwards-winning agency site. Building one from scratch takes a week of GLSL experimentation. @caustics/shader-gradient takes thirty seconds.

This post walks through the full integration process, from install to a production-ready hero with fallback behavior.

Prerequisites

  • An Astro project (v5+)
  • Basic familiarity with Svelte or React
  • Node 22+

Installation

The package ships as a zip with your purchase. Extract it next to your project (a vendor/ folder works well) and install it as a local dependency:

pnpm add ./caustics-shader-gradient

That’s the only dependency. The component bundles its own WebGL code — no Three.js, no peer dependencies.

The Minimal Integration

In any Svelte component or Astro page:

<script>
  import ShaderGradient from '@caustics/shader-gradient/svelte';
</script>

<ShaderGradient preset="caustics" />

By default, ShaderGradient renders as a block element that fills its container. Place it as the first child of a position: relative container with a height and it fills the space.

Choosing a Preset

The full catalog is 37 presets; these six cover the most common use cases:

  • caustics — Indigo/cyan/pink over deep canvas, the flow-algorithm signature. The look on this site’s hero.
  • aurora — Blue/green/purple, slow wave. Works universally.
  • sunset — Orange/pink/purple, warm drift. Good for warm-branded sites.
  • ocean — Deep blue/teal/white, fluid motion. Clean and corporate.
  • neon — Cyan/magenta/yellow, vibrant pulse. Bold, use sparingly.
  • monochrome — Grayscale noise field. Pairs well with colorful UI.

Or skip presets entirely and pass your own colors, speed, grain, and blur.

Custom Configuration

<ShaderGradient
  colors={['#0a0a0a', '#6366f1', '#22d3ee']}
  speed={0.6}
  grain="film"
  grainIntensity={0.12}
  blur={0.5}
  interactive={true}
/>

Set interactive={true} to make the gradient respond to cursor position — the pointer subtly shifts the noise field as it moves (tune the strength with mouseInfluence).

Performance Considerations

The shader runs as a single fullscreen quad — it’s one of the cheapest WebGL operations possible. On a 2020 MacBook Air, the shader gradient uses less than 1% GPU time. But there are a few things to keep in mind:

Cap devicePixelRatio at 2. The component does this by default. On a 3x or 4x display, rendering at native DPI would quadruple the fragment shader workload for imperceptible visual improvement.

Disable on low-power GPUs. Pass reducedMotion="static" to render a static screenshot of the gradient when prefers-reduced-motion is active. The component handles this automatically.

Lazy-load when below the fold. If the shader gradient is not in the hero, use client:visible in Astro to only initialize the WebGL context when the element enters the viewport.

Fallback for No-WebGL Environments

The component detects WebGL availability and falls back to a static CSS gradient that approximates the chosen preset — no configuration required.

Pairing with Grain

Shader gradients look even better with a subtle grain overlay, and it’s built in — no second component needed:

<div class="hero" style="position: relative;">
  <ShaderGradient preset="aurora" grain="film" grainIntensity={0.08} />
  <div class="hero-content">...</div>
</div>

This is exactly how the caustics.dev hero is built.

That’s It

WebGL shader backgrounds are no longer a week-long project. They’re a thirty-second install. The rest of your time is yours.

Buy @caustics/shader-gradient — $39