Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Backgrounds

Free

Particles for React

Specks of dust at three depths that drift, twinkle softly and lean toward the pointer in parallax. For React with Base UI, when a hero or a sign-up panel needs quiet motion behind it.

Framework

Particles fills its container with specks of dust at three depths. Far ones are tiny, faint and a little cooler; middle ones are brighter; a few near ones are large and softly glowing. Each drifts slowly on its own and twinkles gently, and when the pointer moves over the box they all lean toward it, the near ones most and the far ones barely, so the field shifts in parallax. Specks that drift out of one edge fade and come back at the opposite one.

Use it behind a hero, a sign-up card or an empty state, where the motion should stay in the background. For points that sparkle in place rather than drift, use Sparkles; for lines drawn between nearby dots, Constellation; for dots flying toward you, Starfield. It's a small canvas that runs only while it's on screen, with no animation library, and draws a single still frame when reduced motion is on.

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.

Usage

import { Particles } from "@/components/ui/particles";
<Particles className="min-h-[480px]">
  <h1 className="text-5xl font-semibold">Ship faster</h1>
</Particles>

Particles is a container: give it a size, put your content inside, and the specks sit behind it. For a background behind the whole page, pass className="fixed inset-0 -z-10" and no children.

Demos

Drift

driftX and driftY add a steady push in pixels per frame, on top of each speck's own wandering, scaled by depth so near specks fall faster than far ones. Here driftY={0.3} reads as dust settling through light. Specks that fall out of the bottom come back at the top, fading in.

Preview width

Color

particleColor takes any CSS color, here the theme's primary, and the far specks take a cooler, fainter tint of it. intensity="strong" doubles how far the specks lean toward the pointer.

Preview width

Accessibility

The canvas is decoration: it's hidden from assistive tech and never takes the pointer, so your content is read and clicked as usual. With reduced motion it draws the field once, still, and ignores the pointer. The specks are small and spread out, so text in the foreground color stays readable on top; keep copy in text-foreground. Nothing flashes: the twinkle is a slow, shallow swell, and specks fade in and out at the edges.

FAQ

How does the depth work?

Every speck belongs to one of three depths. About half are far: radius size, faint, slow and tinted cooler. About a third are in the middle, 1.6 times as big. The rest are near, 2.5 times as big, brightest and fastest, with a soft halo. Depth also sets how far a speck leans toward the pointer, which is what makes the parallax.

How does the pointer pull work?

Each speck eases toward an offset from the pointer, scaled by its depth and a little randomness, so near and far layers move by different amounts. intensity sets the overall strength, and when the pointer leaves, the specks ease back. interactive={false} turns it off; touch never pulls, so scrolling a page on a phone isn't disturbed.

How many particles should I use?

300 in a 1440×900 box by default; other sizes get as many per area, so a card and a full page look equally dense. Use 150 for a quieter field and up to 600 for a dense one; even 600 costs a small fraction of a millisecond a frame.

Can the particles drift one way?

Yes: driftX and driftY add a steady push in pixels per frame, and speed scales each speck's own wandering and twinkle (0 holds them). driftY={0.3} reads as falling dust; for real snowfall use Snow.

How do I change the color?

Pass particleColor, any CSS color, or set --particles-color on the component. By default it's the text color, so the specks are dark on a light page and light on a dark one, and they follow a theme switch. The far specks mix in a little cool blue on their own.

Does it use the CPU when nobody sees it?

No. The frame loop stops when the background scrolls out of view and the browser pauses it in a hidden tab. With reduced motion it draws once and never loops.

Why do the particles start in the same places?

Their positions come from a fixed seeded sequence rather than Math.random, so every visit starts with the same field. Changing any prop other than particleColor starts the field again from those places.

API Reference

Particles

<div> data-slot="particles"

PropType
count?number

How many specks in a 1440×900 box; other sizes get as many per area, never more than 600.

Default
300
driftX?number

A steady push right (negative: left), in pixels per frame at 60 fps. @default 0.

Default
0
driftY?number

A steady push down (negative: up), in pixels per frame at 60 fps. @default 0.

Default
0
intensity?"subtle" | "medium" | "strong"

How far the specks lean toward the pointer. @default "medium".

Type
"subtle" | "medium" | "strong"
Default
"medium"
interactive?boolean

Whether the specks lean toward the pointer, the near ones most. @default true.

Default
true
particleColor?string

The specks' color, any CSS color; the far ones take a cooler, fainter tint of it. @default "var(--foreground)".

size?number

The far specks' radius in pixels; the middle ones are 1.6 times it, the near ones 2.5 times. @default 1.2.

Default
1.2
speed?number

Multiplies the specks' own slow drift and twinkle; 0 holds them still. @default 1.

Default
1
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

Merged with the part's classes.

CSS variableType
--particles-colorstring

The specks' color (the text color, --foreground).

All 100 backgrounds