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

npm install @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';
</script>

<ShaderGradient preset="aurora" />

By default, ShaderGradient renders as a full-viewport element with position: absolute; inset: 0. Place it as the first child of a position: relative container and it fills the space.

Choosing a Preset

The component ships with six presets that cover the most common use cases:

  • 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.
  • custom — Full control. Pass your own colors, speed, grain, and blur.

Custom Configuration

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

Set interactive={true} to make the gradient respond to cursor position with a subtle parallax tilt. This is the effect on caustics.dev’s homepage hero.

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. You can also provide a custom fallback:

<ShaderGradient preset="aurora">
  <div slot="fallback" class="gradient-fallback" />
</ShaderGradient>

Pairing with Noise Grain

Shader gradients look even better with a subtle grain overlay. Add @caustics/noise-grain at 3–5% opacity on top:

<div class="hero" style="position: relative;">
  <ShaderGradient preset="aurora" />
  <NoiseGrain intensity={0.03} animated />
  <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