A LITTLE LIFE. IN EVERY PIXEL.
Small dots.Big possibilities.
A React animation library. Morph particles into shapes, real UI, and playful interactions.
React · View code
Particles → physics → a real button
import { useRef } from "react";
import { SwarmSurface, swarmActions, type SwarmSurfaceHandle } from "dots-swarm";
// Inside your component:
const surface = useRef<SwarmSurfaceHandle>(null);
const helix = useRef<HTMLDivElement>(null);
const headline = useRef<HTMLHeadingElement>(null);
const button = useRef<HTMLButtonElement>(null);
01 / TAKE SHAPEEvery state.
Every state.
A little more alive.
171 particle shapes for React. Change one prop; the same dots morph into the next shape.
Find your shapeA shape is a prop
import { DotSwarm } from "dots-swarm";
<DotSwarm
shape="wire-sphere"
color="#ffffff"
count={1300}
style={{ height: 400 }}
/>
LIVE PREVIEW1,300 particles
wire sphere Scroll to morph02 / BECOME THE INTERFACEPACKAGE PRIMITIVES
The dots become
the interface.
Real components. One living material.
Pick a primitive. Watch it come together.
Click it. Then try another primitive.
import { SwarmButton } from "dots-swarm/ui"Composable parts. Radix behavior. Your styles.Use the primitives
Button primitive
import { SwarmUI, SwarmButton } from "dots-swarm/ui";
import "dots-swarm/ui.css";
<SwarmUI.Root active="button" style={{ height: 320 }}>
<SwarmUI.Scene name="button">
<SwarmButton onClick={() => alert("Hello!")}>
Make something
</SwarmButton>
03 / CONNECT THE MOMENTSThe magic is
The magic is
in between.
Let it scatter. Shift the color. Turn a thought into something tangible. Choreograph the whole journey.
Play in StudioColorDensityDispersionMotion
Choreograph every property
import { SwarmSequence } from "dots-swarm";
// progress: 0–1 from a slider or useSwarmScroll().
<SwarmSequence animate progress={progress}
style={{ height: 420 }} keyframes={[
{ at: 0, shape: "halo", color: "#9bbcff", scale: 1.1 },
{ at: 0.26, shape: "halo", dispersion: 0.15, rotation: 0.5 },
{ at: 0.5, shape: "cloud", dispersion: 0.9, density: 0.55,
04 / ADD A LITTLE CHARACTERA thousand dots.
A thousand dots.
One personality.
A little tension. A big reaction. Give him a moment to pull himself together.
Give it a reaction
import { useRef } from "react";
import { SwarmSurface, swarmActions, type SwarmSurfaceHandle } from "dots-swarm";
// Inside your component:
const surface = useRef<SwarmSurfaceHandle>(null);
const avatar = useRef<HTMLDivElement>(null);
<SwarmSurface ref={surface} color="#4199ef" viewport
You have my attention.Move around. I’m listening.
05 / YOUR TURNOpen Studio
What will you make of it?
A sequence, ready for your app
import { DotsSequence, DotsSequencePlayer } from "dots-swarm";
import { proShapes } from "@dots-swarm/pro";
const sequence = new DotsSequence([
{ shape: "cloud", duration: 4.2 },
{ shape: "microphone", duration: 4.2 },
{ shape: "thought-bubble", duration: 4.2 },
{ shape: "neural-network", duration: 4.2 },
Your colors. Your pace. Your choreography.Read the docs
import { SwarmUI, SwarmButton } from "dots-swarm/ui";
import "dots-swarm/ui.css";
<SwarmUI.Root active="button" style={{ height: 320 }}>
<SwarmUI.Scene name="button">
<SwarmButton onClick={onContinue}>
Make something
</SwarmButton>
</SwarmUI.Scene>
</SwarmUI.Root>Make the next
thing feel alive.
Free to start. More to play with.