Glin UI
Signature / Molecule

Particle Field

Ambient floating particle system with CSS-only staggered animations.

Realtime

Presence for every page, in one hook

Show who is viewing, typing and pointing without running your own socket servers or paying per connection.

Works with

  • Vercel
  • GitHub
  • Cloudflare
  • Astro

Installation$

Install from
pnpm dlx @glinui/cli@latest add particle-field

Prefer the package?

Usage$

Place ParticleField inside a relative container with overflow-hidden. Particles float upward with deterministic positioning, no layout shift between renders.

Examples$

Variants$

Default
Squares
Long drift
import { ParticleField } from "@glinui/ui"
export function Variants() {
return (
<div data-glin-theme="dark" className="grid w-full gap-3 sm:grid-cols-3">
<div className="relative isolate flex h-44 items-end overflow-hidden rounded-xl bg-[var(--surface-0)] p-3">
<ParticleField count={30} />
<span className="relative z-10 rounded-full bg-black/70 px-2.5 py-1 text-xs font-medium text-white">Default</span>
</div>
<div className="relative isolate flex h-44 items-end overflow-hidden rounded-xl bg-[var(--surface-0)] p-3">
<ParticleField count={30} shape="square" maxSize={5} />
<span className="relative z-10 rounded-full bg-black/70 px-2.5 py-1 text-xs font-medium text-white">Squares</span>
</div>
<div className="relative isolate flex h-44 items-end overflow-hidden rounded-xl bg-[var(--surface-0)] p-3">
<ParticleField count={24} distance={140} duration={10} />
<span className="relative z-10 rounded-full bg-black/70 px-2.5 py-1 text-xs font-medium text-white">Long drift</span>
</div>
</div>
)
}

Behind a dashboard header$

Production, last 24 hours

API overview

Requests
2.41M
+8.2% vs yesterday
p95 latency
184 ms
-12 ms vs yesterday
Error rate
0.03%
-0.01% vs yesterday
import { ParticleField, Button, Heading, Text } from "@glinui/ui"
const stats = [
["Requests", "2.41M", "+8.2%"],
["p95 latency", "184 ms", "-12 ms"],
["Error rate", "0.03%", "-0.01%"]
]
export function UsageHeader() {
return (
<section data-glin-theme="dark" className="relative isolate flex min-h-[22rem] w-full flex-col justify-end gap-6 overflow-hidden rounded-xl bg-[var(--surface-0)] p-6 sm:p-8">
<ParticleField count={40} />
<div className="relative z-10 flex flex-wrap items-end justify-between gap-4">
<div className="flex flex-col gap-1">
<Text variant="eyebrow">Production, last 24 hours</Text>
<Heading level={2} size="md">API overview</Heading>
</div>
<div className="flex gap-2">
<Button size="sm" variant="outline">Export CSV</Button>
<Button size="sm">Create alert</Button>
</div>
</div>
<dl className="relative z-10 grid gap-3 sm:grid-cols-3">
{stats.map(([label, value, delta]) => (
<div key={label} className="rounded-xl border border-[var(--line-soft)] bg-[var(--surface-1)] p-4">
<dt className="text-xs text-[var(--color-muted)]">{label}</dt>
<dd className="mt-1 text-2xl font-semibold tabular-nums text-[var(--color-foreground)]">{value}</dd>
<dd className="text-xs text-[var(--tone-success-text)]">{delta} vs yesterday</dd>
</div>
))}
</dl>
</section>
)
}

Accessibility$

  • The component renders with aria-hidden, invisible to assistive technologies.
  • Purely decorative; carries no semantic meaning.

Reduced Motion$

All particle animations are paused via motion-reduce:[animation:none]. The static particles remain visible.

API Reference$

PropTypeRequiredDefaultDescription
colorstringNo-Particle color
countnumberNo30Number of particles
distancenumberNo200Float distance in px
durationnumberNo5Float duration in seconds
maxSizenumberNo5Max particle size in px
minSizenumberNo2Min particle size in px
shape"circle" | "square"No"circle"Particle shape

Source$

import { ParticleField } from "@glinui/ui"
packages/ui/src/components/particle-field.tsx

Generated API Snapshot

Beta

Auto-extracted from TypeScript source in packages/ui/src/components/particle-field.tsx. This section is in beta and may lag behind hand-curated docs. Regenerate with pnpm --filter @glinui/docs api:generate.

Generated: 2026-10-08T01:41:21.546Z · Full index: /docs/api-metadata

Primary Props Type

ParticleFieldProps

ParticleFieldProps

PropTypeRequiredDefaultDescription
colorstringNo-Particle color
countnumberNo30Number of particles
distancenumberNo200Float distance in px
durationnumberNo5Float duration in seconds
maxSizenumberNo5Max particle size in px
minSizenumberNo2Min particle size in px
shape"circle" | "square"No"circle"Particle shape