Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Backgrounds

Pro

Swarm Background for React

A flock of slender darts with soft tails that form schools, split and merge by the boids rules. For React with Base UI, when a page about agents, biology or generative art needs motion that looks alive.

Framework

Swarm is a flock of slender darts following Craig Reynolds' boids rules: each one matches its neighbours' heading, steers toward their centre and keeps its distance from the closest ones. Nobody leads, yet schools form, glide, split and merge on their own, and a slow current that wants different headings in different places keeps them spread over the whole box instead of collapsing into one. Each boid trails a soft tail along its path, and they come in three depths, smaller and fainter far away. The box wraps around, so a boid leaving one edge comes back on the other. With interactive, the boids scatter away from the pointer and gather again behind it.

It suits pages about agents, biology or generative art. For dots that drift without flocking, use Particles; for nodes linked by lines, Constellation; for another set of local rules with emergent patterns, Life. It's a small canvas that pauses offscreen and shows one settled flock with reduced motion.

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 { Swarm } from "@/components/ui/swarm";
<Swarm className="min-h-[480px]">
  <h1 className="text-5xl font-semibold">Ship faster</h1>
</Swarm>

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

Demos

Tight flocks

cohesion={1.5} pulls each boid harder toward its neighbours and alignment={1.5} makes them agree on a heading sooner, so the boids gather into denser schools that wheel and merge, like a murmuration. Lowering separation as well packs them into tight balls.

Preview width

Interactive

With interactive, boids within 90 px of the pointer turn away from it, three times as hard as they follow the flock, then regroup once it passes. boidColor sets the color; here a cyan on bg-slate-950.

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 simulates ahead without drawing, shows one settled flock and stops; the pointer is ignored. The near darts cross your text at full color, which large bold headings handle well; for longer copy, dim the flock with *:data-[slot=swarm-layer]:opacity-60 on the component and keep the text in text-foreground. Nothing flashes.

FAQ

What rules drive the flock?

Within 55 px, each boid matches its neighbours' heading and steers toward their centre; within 26 px it moves apart. Each pull is a capped turn, so no boid can turn sharply, and alignment, cohesion and separation weight them. A gentle current, a smooth field of headings that drifts over time, nudges every boid too, so schools split up and wheel around the box.

How do I tune the feel?

Raise cohesion and lower separation for tight balls, and the reverse for a loose drift. Lower alignment and the boids stop agreeing on a heading. speed runs the whole flight faster or slower, and 0 holds it still.

How many boids can I use?

300 in a 1440×900 box by default; other sizes get as many per area (a few more in small boxes), never more than 300. Every boid compares itself with every other, so the cost grows with the square of the count, but each boid looks around only every other frame, so even 300 stays well under a millisecond a frame, at 60 or 120 Hz.

What happens at the edges?

The space wraps around: a boid leaving the right edge comes back on the left, and boids see neighbours across the edge, so flocks don't break up there.

Does the flock react to the pointer?

Only with interactive: boids within 90 px of the pointer flee it, then close up again. It's off by default, and touch never scatters them, so scrolling on a phone isn't disturbed.

Does it respect reduced motion?

Yes. It flies the flock 100 frames ahead without drawing them, draws one settled frame and stops; the pointer is ignored. The loop also stops when the background scrolls out of view.

API Reference

Swarm

<div> data-slot="swarm"

PropType
alignment?number

How strongly each boid matches its neighbours' heading. @default 1.

Default
1
boidColor?string

The boids' color, any CSS color. @default "var(--primary)".

cohesion?number

How strongly each boid steers toward its neighbours' centre. @default 1.

Default
1
count?number

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

Default
300
interactive?boolean

Whether the boids flee the pointer. @default false.

Default
false
separation?number

How strongly each boid keeps away from the closest ones. @default 1.

Default
1
speed?number

Multiplies the pace of the flight; 0 holds the flock 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
--swarm-colorstring

The boids' color (--primary).

All 100 backgrounds