Animated gradient background for shadcn/ui
Add a moving gradient background to a shadcn/ui or React app with one CLI command, in your theme colours.
To add an animated gradient background to a shadcn/ui app, install a gradients.sh component with the shadcn CLI and wrap your content in it:
npx shadcn@latest add https://gradients.sh/r/hero-background.jsonThe gradient is drawn live on the GPU (WebGPU, or WebGL2 where WebGPU isn't available), loops seamlessly and takes its colours from your theme. It isn't a video or an image, so it stays sharp at any size and adds about 50 KB of gzipped JavaScript.
Your headline
The gradient fades into the page.
import { HeroBackground } from "@/components/hero-background";
export function HeroBackgroundDemo() {
return (
<HeroBackground className="min-h-[400px]">
<h1 className="text-4xl font-semibold tracking-tight text-white">
Your headline
</h1>
<p className="mt-3 text-white/75">The gradient fades into the page.</p>
</HeroBackground>
);
}
Before you start
You need a React project set up for shadcn/ui, which means it has a components.json. Next.js, Vite, React Router and TanStack Start all work. If you don't have one yet:
npx shadcn@latest init1. Install a component
Pick the component for the job:
- Hero Background is a full-bleed
<section>with centred content, a bottom edge that fades into the page, and a little pointer and scroll response. Use it for a landing page hero. - Mesh Gradient is a plain box filled with soft drifting colour. Use it behind any section, card or panel.
pnpm dlx shadcn@latest add https://gradients.sh/r/hero-background.jsonThe CLI copies components/hero-background.tsx, the shared components/gradient-surface.tsx and the engine in lib/gradient-engine/ into your project. You own the code, so you can read and change every line. A second component reuses the surface and the engine.
2. Add it to a page
Hero Background takes its content as children. The example uses shadcn's Button; add it with npx shadcn@latest add button if your project doesn't have it yet.
import { Button } from "@/components/ui/button";
import { HeroBackground } from "@/components/hero-background";
export default function Page() {
return (
<HeroBackground>
<h1 className="text-5xl font-semibold tracking-tight text-white">
Ship your next launch
</h1>
<p className="mt-4 max-w-md text-white/75">
A live gradient behind your headline, drawn on the GPU.
</p>
<Button className="mt-8" size="lg">
Get started
</Button>
</HeroBackground>
);
}The component files start with "use client", so you can import them from a Next.js Server Component as above. The server renders the gradient's colours as a CSS background at its final size, and the first GPU frame replaces it in place, so nothing shifts while the page loads.
Hero Background draws a mesh gradient by default. Set kind to "grain", "aurora", "waves", "radial-glow" or "linear-flow" for one of the other five free looks, or fade={false} for a hard bottom edge.
Behind any section
For a background that isn't a hero, use Mesh Gradient (or any of the six background components) and give it a size. It fills its box and renders children on top. Install it first; it reuses the surface and engine you already have:
pnpm dlx shadcn@latest add https://gradients.sh/r/mesh-gradient.jsonimport { MeshGradient } from "@/components/mesh-gradient";
<MeshGradient className="h-[360px] rounded-xl p-10">
<h2 className="text-3xl font-semibold text-white">Pricing that scales</h2>
</MeshGradient>;3. Use your theme colours
Every colour prop accepts any CSS colour, including shadcn's CSS variables. Pass two to six colors and a background for the base underneath:
<HeroBackground
colors={["var(--primary)", "var(--chart-2)", "var(--chart-4)"]}
background="var(--background)"
>
{children}
</HeroBackground>When the class on <html> changes, the components re-read the variables, so shadcn's dark mode and next-themes with attribute="class" switch the gradient along with the rest of the page. Theming has the details.
4. Tune the motion
The common props, shared by every component:
| Prop | Range | What it does |
|---|---|---|
speed | 0 to 2 | How far the gradient travels per loop. 0 holds it still. |
loopSeconds | 4 to 30 | The animation repeats exactly every loopSeconds. |
scale | 0.25 to 4 | Higher means smaller shapes. |
warp | 0 to 1 | How strongly the shapes swirl. |
grain | 0 to 1 | Film grain over the colour. |
blur | 0 to 1 | Softness. |
Each component's props table lists the rest. To skip the trial and error, tune a gradient in the editor or start from one of the presets, then install exactly what you see. Presets and exports shows how.
Performance
A moving background shouldn't cost you your Core Web Vitals. The engine handles the usual problems:
- Gradients that are off screen or in a hidden tab stop drawing.
- The canvas renders at no more than 1.5× device pixels. Lower
maxDprfor full-screen gradients on slow phones. - Visitors who prefer reduced motion see one still frame.
- A browser with neither WebGPU nor WebGL2 keeps the server-rendered CSS gradient.
Two or three moving gradients on a page stay well inside the budget. The technical FAQ has the limits.
Without the shadcn CLI
On a page that isn't set up for shadcn, such as plain HTML, Vue, Svelte or a site builder, copy an embed snippet from the editor instead. See Embed.