Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Backgrounds

Pro

Constellation Background for React

A web of drifting nodes joined by thin lines that fade with distance, pushed aside by the pointer. For React with Base UI, when an AI, data or infrastructure page needs a connected network behind its content.

Framework

Constellation is a web of slowly drifting nodes joined by thin lines that fade with distance, so the network keeps breaking and re-forming as the nodes move. The pointer pushes nearby nodes away, and ripples run through the web; the nodes then ease back to their own drift. The nodes take the theme's primary color and the lines its muted text color, so the web follows light and dark mode, and it fades out toward the edges.

It suits AI, data and infrastructure pages. For dots without lines, use Particles; for agents that steer together instead of drifting, Swarm; for a tidy wired network with pulses, Circuit. It's a small canvas that pauses offscreen and holds still 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 { Constellation } from "@/components/ui/constellation";
<Constellation className="min-h-[480px]">
  <h1 className="text-5xl font-semibold">Ship faster</h1>
</Constellation>

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

Demos

Card

count doesn't grow with the box, so a small card needs fewer nodes and shorter links: here count={36} and connectionDistance={110}.

Preview width

Color

nodeColor and lineColor take any CSS color. A sky blue on bg-neutral-950 gives the classic night-sky network; the halo takes the node color.

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 web once, still, and ignores the pointer. Lines are at most 50% of the muted text color and the nodes are small, so text in the foreground color stays readable on top; keep copy in text-foreground. Nothing flashes: lines fade in and out with distance, never all at once.

FAQ

How are the lines drawn?

Every pair of nodes closer than connectionDistance (150 px by default) gets a line whose opacity falls with distance. The lines are grouped into six opacity steps, so a whole frame is six strokes, however many lines there are.

Isn't checking every pair slow?

80 nodes make 3,160 pairs, a small fraction of a millisecond a frame; 300 nodes, the most it draws, stay well under a millisecond. Drawing the lines costs more than finding them, so lower connectionDistance before count.

How does the pointer interact?

Nodes within 100 px of the pointer are pushed away, harder the closer they are, then ease back to their own drift. interactive={false} turns it off; touch never pushes, so scrolling on a phone isn't disturbed.

Can I change the colors?

nodeColor and lineColor take any CSS color; by default they're the theme's primary and muted text colors, so they follow light and dark mode. glow={false} drops the soft halo for a crisper look on light pages.

Why is my small card so busy?

count doesn't scale with the size of the box. In a small container use fewer nodes (30 to 40) or a shorter connectionDistance.

Can the web fill the box to the edges?

Yes: fade="none" turns the edge fade off. top and bottom fade only that edge. The fade is a mask, so it blends into whatever background is behind the component.

API Reference

Constellation

<div> data-slot="constellation"

PropType
connectionDistance?number

Nodes closer than this, in pixels, are joined by a line. @default 150.

Default
150
count?number

How many nodes; more than 300 are drawn as 300. @default 80.

Default
80
fade?"none" | "radial" | "top" | "bottom"

Where the web fades out: toward every edge from the centre (radial), toward the top, or toward the bottom. It's a mask, so the web fades into whatever is behind it.

Type
"none" | "radial" | "top" | "bottom"
Default
"radial"
glow?boolean

A soft halo around each node. @default true.

Default
true
interactive?boolean

Whether the pointer pushes nearby nodes away. @default true.

Default
true
lineColor?string

The lines' color, any CSS color, drawn at up to 50% opacity. @default "var(--muted-foreground)".

nodeColor?string

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

nodeSize?number

Each node's radius is 0.5 to 1.5 times this, in pixels. @default 2.

Default
2
speed?number

Multiplies the drift; 0 holds the nodes 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
--constellation-line-colorstring

The lines' color (--muted-foreground).

--constellation-node-colorstring

The nodes' color (--primary).

All 100 backgrounds