Particles

Free · MIT

Canvas particles drift gently, link up with fine lines and move out of the pointer's way; density scales with the area.

MarkdownOpen in v0
Open in v0

Installation

$ npx shadcn@latest add https://goodui.dev/r/particles.json

The file lands in components/goodui/particles.tsx and is yours to edit. With the @goodui registry added, npx shadcn@latest add @goodui/particles works too.

Usage

import type { ReactNode } from "react"
import { Particles } from "@/components/goodui/particles"

export function LoginBackdrop({ children }: { children: ReactNode }) {
  return (
    <main className="relative grid min-h-svh place-items-center overflow-hidden bg-background">
      <Particles color="var(--primary)" density={1.2} />
      <div className="relative w-full max-w-sm rounded-2xl border bg-card p-6 shadow-sm">{children}</div>
    </main>
  )
}

When to use

Use it for
  • Hero sections of AI, data or network products, where linked dots suggest connections.
  • Login and sign-up screens that need gentle motion behind a centered form.
  • Interactive landing sections where the background should move out of the cursor's way.
Reach for something else
  • A still texture: use dot-grid.
  • Soft color without detail: use aurora, which is CSS-only.
  • Behind dense app UI or long text: moving dots and lines compete with content. Use dot-grid with a fade.
If you needUse
Constellation with linesdefaults (connect, repel)
Floating dust, no linesconnect={false} density={2}
Background only, no pointer reactionrepel={false}
Brand coloredcolor="var(--primary)"
Lighter on low-end devicesdensity={0.8} maxParticles={120} or connect={false}

Examples

Dust only, no lines, no pointer reaction

<Particles connect={false} repel={false} density={2} size={[0.5, 1.2]} speed={6} />

API reference

PropTypeDefault
density
Particles per 10,000 px² of area.
number1.4
maxParticles
Hard cap on the particle count.
number220
size
Radius range in px.
[number, number][0.6, 1.8]
speed
Drift speed in px per second.
number10
connect
Draw lines between nearby particles.
booleantrue
linkDistance
Max distance for a connecting line, in px.
number110
repel
Push particles away from the pointer (listens on the parent element).
booleantrue
repelRadius
Distance in px within which the pointer pushes particles away.
number110

Also accepts every <div> attribute.

Accessibility

  • The canvas wrapper is aria-hidden and has pointer-events: none, so content above it stays clickable.
  • Reduced motion shows one still frame.

Motion

  • Each particle drifts in its own direction at 40% to 100% of `speed` px per second (10) and wraps around the edges.
  • With connect, particles closer than `linkDistance` px (110) are joined by thin lines that fade with distance.
  • With repel, the pointer pushes particles within `repelRadius` px (110) away; they ease back to their own drift.
  • It pauses while off-screen and while the tab is hidden. Reduced motion: one still frame is drawn.
  • Canvas 2D, devicePixelRatio capped at 2. The count is density per 10,000 px² of area, capped by maxParticles (220).
  • Lines are checked between every pair of particles, so cost grows quickly with the count; lower density or turn off connect on large areas.
  • The color is resolved once and re-read when the theme class on <html> or the system color scheme changes.

Notes for AI

Coding agents read these rules through MCP and llms.txt, or paste this page with Copy page.

  • Place it inside a relative parent; it fills it with absolute inset-0. Give the content after it position: relative.
  • repel listens to pointer moves on the parent element, since the canvas itself ignores the pointer.
  • size is a [min, max] radius tuple in px; speed is px per second.
  • color accepts any CSS color or variable and is resolved for canvas automatically.

FAQ

Is this tsParticles or particles.js?

No. It is a small hand-written Canvas 2D component with no dependencies.

Does it follow dark mode?

Yes. With the default var(--foreground), or any theme variable, it re-reads the color when the theme changes.

Related