Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Shaders

Pro

Magma Shader for React

A lava river seen from above, drawn on the GPU: black crust plates drift and grind past each other while the seams between them glow red to yellow. For React with Base UI, when a gaming, launch or product hero needs heat and slow motion behind its copy.

Framework

Magma Shader draws a river of lava seen from above. Black crust plates drift down the frame, each one wandering a little on its own, so neighbours grind past each other and the seams between them open and close. The seams glow from deep red to orange-yellow, hottest and widest where the plates pull apart, and a few plates have split across the middle, showing a thinner, cooler crack. The plates are Voronoi cells with ragged, noise-warped borders, and the glow's color is black-body light, worked out from Planck's law for each seam's temperature, by a WGSL fragment shader on WebGPU for every pixel, every frame.

Use it behind a gaming or launch hero, a product drop, or a dark section that should feel hot without moving fast. Most of the frame is dark crust, so a headline sits easily on it. For flame rather than molten rock, use Fire 3D Shader; for a bed of coals breathing in the dark, Embers Shader; for a page edge that burns in, Burning Paper Shader; and for a fire in plain CSS, with no GPU, the Fireplace background. It runs only while it's on screen, holds a still frame with reduced motion, and shows dark crust with two glowing seams in browsers without WebGPU.

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Usage

import { MagmaShader } from "@/components/ui/magma-shader";
<MagmaShader className="flex min-h-[32rem] items-center justify-center">
  <h1 className="text-5xl font-semibold text-white">Forged in fire</h1>
</MagmaShader>

Magma Shader is a container: your content sits on top of the lava, in normal flow. It fills its own box, so give it a height or content. For a backdrop behind the whole page, render it empty with className="fixed inset-0 -z-10". The crust is near black in both color schemes, so put white or light text over it.

Demos

Cooling

temperature={900} cools the seams to a dull red, cracks={0.3} narrows them and splits fewer plates, and flow={0.5} slows the river to half pace, for a calmer, darker surface.

Preview width

In a card

The plates are sized to the box's height, so a card shows as many rows of them as a hero, only smaller. cracks={0.8} widens the seams and splits more plates, so the small surface still glows.

Preview width

Performance

About 1.4 ms of GPU time a frame at 1280×720 on an M2 Max laptop; slower GPUs take several times longer. The seams are thin, sharp lines, so it renders at full resolution by default: quality={0.5} costs a quarter as much, but softens them. The animation stops when the shader scrolls out of view, and the browser pauses it in a hidden tab. Every shader on a page shares one GPU device and one frame loop, and vgpu (about 50 KB gzipped) loads only when the first one mounts.

Browser support

The shader needs WebGPU: Chrome and Edge, Safari 26 and later, and Firefox on Windows and macOS. Elsewhere, and until the first frame, the box shows a CSS gradient in the crust color with two faint glowing seams, so the layout never jumps. data-state on the root reads unsupported there, if you want to style around it. See Shader Canvas.

Accessibility

The lava is decoration: it's hidden from assistive tech and lets every click through to your content. With reduced motion it draws one still frame, four seconds in, and stops. Nothing flashes: the plates drift and the heat breathes over seconds. White text reaches 4.5:1 on 98% of the default frame, and more than 16:1 on 95% of it; only the brightest seams fall below. Keep small body text off them, or raise cracks and intensity only where there's no text.

FAQ

How is the lava drawn?

The crust is a Voronoi diagram: the plane is split into cells around scattered points, and each cell is a plate. The points wander on slow orbits while the whole pattern drifts down the frame, so the plates move against each other, and a noise warp makes their borders ragged. Each pixel's distance to the nearest border makes the seam, a noise field widens it where the plates pull apart, and the seam's temperature, through Planck's law, gives its color.

What does temperature change?

The seams' color, as a real hot body's would change: at 800 K they're a dull, dim red, at the default 1300 K orange with yellow where they're widest, and at 2000 K yellow-white. The brightness follows too, so a cool flow is darker. intensity sets the glow's strength on top, from 0, plain crust, to 2.

Can I change the colors?

crustColor sets the plates and tintColor multiplies the glow: white keeps the black-body colors, and a pale color tints them, such as #ffd8c0 for a rosier glow. Both take any CSS color and follow a theme switch, so var(--primary) works. For the warm colors themselves, temperature is the natural knob.

What's the difference between flow and speed?

flow moves the plates: at 0 they hold still while the heat in the seams still breathes, and at 2 the river runs twice as fast. speed scales the whole clock, plates and heat alike, and 0 holds the frame. paused holds it too, and time draws one fixed moment, in seconds.

Will it slow my page down?

It costs about 1.4 ms of GPU time a frame at 1280×720 on an M2 Max laptop, and the CPU only sets a few numbers each frame. It stops when it's off screen. On a slow GPU or a large screen, quality={0.5} renders at half resolution, a quarter of the pixels, at the cost of softer seams. cracks, temperature and flow change the look, not the cost.

What happens in browsers without WebGPU?

The box keeps its CSS gradient, dark crust with two faint glowing seams and a red glow at the bottom, so the page still looks finished. Nothing errors: the root's data-state reads unsupported.

API Reference

MagmaShader

data-slot="magma-shader"

PropType
cracks?number

How broken the crust is, from 0 (narrow seams, no fine cracks) to 1 (wide seams, cracked plates). @default 0.5.

Default
0.5
crustColor?string

The cooled crust plates. Any CSS colour. @default "#140d0b".

Default
"#140d0b"
fallback?string

What shows until the first frame and in browsers without WebGPU: a CSS background value (gradients, sizes, a colour) that looks like the shader. It can use the colour props' --shader-<field> variables.

flow?number

How fast the river carries the plates, on top of speed, from 0 (the plates hold still while the heat still moves) to 2. @default 1.

Default
1
intensity?number

How bright the seams glow, from 0 (dark crust) to 2. @default 1.

Default
1
interactive?boolean

Whether u.pointer follows the pointer. @default false.

paused?boolean

Holds the current frame. @default false.

quality?number

Render scale, from 0.25 to 1, of the screen's pixels (capped at 2×). @default 1.

speed?number

Animation speed: 1 is normal, 0 holds the frame. @default 1.

temperature?number

The seams' temperature in kelvin, from 800 (a dull red) to 2000 (yellow-white): it sets their colour. @default 1300.

Default
1300
time?number

A fixed moment, in seconds: draws it and doesn't animate.

tintColor?string

Multiplies the glow's colour: white keeps the black-body colours. Any CSS colour. @default "#ffffff".

Default
"#ffffff"
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Forwarded to the part.

All 101 shaders