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, andblur.
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.