npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

jl-particle-interactive

v0.2.2

Published

Canvas-based React library for particle text animations and interactive backgrounds — spring physics, magnetic hover, click attract/repel, NET/JELLYFISH modes. TypeScript. Zero dependencies.

Readme

jl-particle-interactive — React Canvas Particle Animations

npm version npm downloads bundle size license TypeScript

A canvas-based React library for rendering text and backgrounds as thousands of animated particles. Letters form from particle swarms, respond to magnetic hover, attract or repel on click, and backgrounds come alive with NET graphs, JELLYFISH glows, or pointer-following swarms. Built with zero runtime dependencies, full TypeScript support, and DPR-aware rendering for sharp output on retina displays.

Requires React 18+. No global CSS. Zero runtime dependencies.


Why jl-particle-interactive?

| Feature | jl-particle-interactive | tsparticles | particles.js | |---|---|---|---| | Text that forms from particles | ✓ (native, spatial coherence) | Plugin only (complex setup) | ✗ | | Spring physics + float noise | ✓ | ✗ | ✗ | | Magnetic hover / click interact | ✓ (attract & repel) | ✗ | ✗ | | Ready-made background presets | ✓ NET, JELLYFISH, FOLLOW_POINTER | General engine (DIY) | General engine (DIY) | | Runtime dependencies | Zero | 14+ packages | 0 (vanilla JS only) | | React integration | Native React hooks | Wrapper package needed | Manual integration | | TypeScript | Strict mode | Partial | ✗ | | DPR-aware (retina) | ✓ | ✗ | ✗ |


Use cases

  • Hero section animated titles — Text materializes from particle chaos on page load
  • Loading screens — Words form and dissolve while content loads
  • Interactive word carousels — Cycle through words; particles re-form smoothly
  • Animated backgrounds — NET graph, JELLYFISH glow, or pointer-following swarm behind any content

Installation

npm install jl-particle-interactive

Framework compatibility

| Framework | Supported | |---|---| | Vite + React | ✓ | | Next.js (App Router & Pages) | ✓ (client components only — add 'use client') | | Create React App | ✓ | | Remix | ✓ (client-side only) | | Astro | ✓ (inside client:only components) | | TypeScript | ✓ (strict mode, declarations included) |


What it offers

| Feature | Description | |---|---| | Text particles | Thousands of canvas particles that form any text string using pixel-sampling with spatial coherence — letters look sharp at any size | | Magnetic hover | Particles are attracted to the cursor on hover (~173px radius spring force) | | Click interactions | Attract or repel particles on click/tap — particles flee or swarm toward the pointer | | Animated backgrounds | NET (connected node graph), JELLYFISH (organic glow rings), and FOLLOW_POINTER (swarm) modes | | Spring physics | Each particle uses spring + friction + float-noise physics — movement feels natural, never robotic | | Customizable | Colors (hex or RGB palettes), shapes (circle, square, bean), density, speed, ease, and more |


Quick start

import { ParticleCanvas, TextParticleEngine } from 'jl-particle-interactive';

export default function App() {
  return (
    <ParticleCanvas height="60vh">
      <TextParticleEngine text="Hello" />
    </ParticleCanvas>
  );
}

Examples

Text with a color palette

Assign multiple colors and each particle picks one at random.

<ParticleCanvas height="60vh">
  <TextParticleEngine
    text="React"
    particleColor={['#ff6b6b', '#feca57', '#48dbfb']}
    particleSize={1.5}
  />
</ParticleCanvas>

Repel on click

Particles flee from the cursor while the mouse button is held down.

<ParticleCanvas height="60vh">
  <TextParticleEngine
    text="Boom"
    clickMode="repel"
    particleEase={2}
  />
</ParticleCanvas>

Attract on click

The opposite — particles swarm toward the cursor on press.

<ParticleCanvas height="60vh">
  <TextParticleEngine
    text="Pull"
    clickMode="attract"
    isMagnet={false}
  />
</ParticleCanvas>

Animated NET background

A connected particle network moves behind your content.

<ParticleCanvas
  height="80vh"
  background={{
    name: 'NET',
    color: '#4ecdc4',
    density: 0.8,
  }}
>
  <TextParticleEngine text="Network" particleColor="#ffffff" />
</ParticleCanvas>

Jellyfish background

Smooth, organic blobs that drift across the canvas.

<ParticleCanvas
  height="80vh"
  background={{
    name: 'JELLYFISH',
    colors: ['#ff6b6b', '#a29bfe', '#00cec9'],
    colorMode: 'wave',
  }}
>
  <TextParticleEngine text="Fluid" particleColor="#ffffff" />
</ParticleCanvas>

Dynamic text

Change the text prop and the particles re-form automatically.

const words = ['Hello', 'World', 'React'];

export default function Carousel() {
  const [index, setIndex] = useState(0);

  useEffect(() => {
    const id = setInterval(() => setIndex(i => (i + 1) % words.length), 2000);
    return () => clearInterval(id);
  }, []);

  return (
    <ParticleCanvas height="60vh">
      <TextParticleEngine text={words[index]} />
    </ParticleCanvas>
  );
}

Background guide

The background prop on ParticleCanvas supports four usage patterns:

  1. No animated background
  2. FOLLOW_POINTER swarm background
  3. NET node-link graph background
  4. JELLYFISH organic glow/swim background

1) No background engine

Use this when you only want text particles.

<ParticleCanvas background={{ name: 'NONE' }}>
  <TextParticleEngine text="Only Text" />
</ParticleCanvas>

2) FOLLOW_POINTER background

Particles form a swarm that follows the cursor smoothly.

<ParticleCanvas
  background={{
    name: 'FOLLOW_POINTER',
    orientation: 'diagonal',
    density: 1,
    shape: 'bean',
    colors: ['#00d4ff', '#6ee7b7', '#facc15'],
    colorMode: 'wave',
    particleSpeed: 1,
    pointerTrackingSpeed: 0.06,
  }}
>
  <TextParticleEngine text="Follow" particleColor="255, 255, 255" />
</ParticleCanvas>

3) NET background

Moving nodes connect with lines. Great for tech-style hero sections.

<ParticleCanvas
  background={{
    name: 'NET',
    density: 0.9,
    shape: 'circle',
    colors: ['#7dd3fc', '#60a5fa'],
    colorMode: 'mixed',
    particleSpeed: 1,
    pointerTrackingSpeed: 0.08,
  }}
>
  <TextParticleEngine text="Network" particleColor="255, 255, 255" />
</ParticleCanvas>

4) JELLYFISH background

Soft organic particle body with pulse/swimming motion.

<ParticleCanvas
  background={{
    name: 'JELLYFISH',
    density: 1.1,
    shape: 'bean',
    colors: ['#f472b6', '#a78bfa', '#22d3ee'],
    colorMode: 'wave',
    particleSpeed: 1,
    pointerTrackingSpeed: 0.02,
  }}
>
  <TextParticleEngine text="Jelly" particleColor="255, 255, 255" />
</ParticleCanvas>

Background with transparent stage

Use backgroundColor="transparent" to place particles over your own image/gradient layer.

<div style={{ background: 'linear-gradient(135deg, #0f172a, #111827)' }}>
  <ParticleCanvas
    height="70vh"
    backgroundColor="transparent"
    background={{ name: 'NET', density: 0.7, color: '#67e8f9' }}
  >
    <TextParticleEngine text="Overlay" backgroundColor="transparent" />
  </ParticleCanvas>
</div>

Full BackgroundCanvas type

type BackgroundModeName = 'NONE' | 'FOLLOW_POINTER' | 'NET' | 'JELLYFISH';
type ParticleOrientation = 'vertical' | 'horizontal' | 'diagonal';

interface BackgroundCanvas {
  name: BackgroundModeName;
  orientation?: ParticleOrientation;
  density?: number;
  color?: string;
  colors?: string[];
  colorMode?: 'wave' | 'mixed';
  interactionRadius?: number;
  lineDistance?: number;
  shape?: 'circle' | 'square' | 'bean';
  particleSpeed?: number;
  pointerTrackingSpeed?: number;
}

Option matrix (what applies to each mode)

| Option | FOLLOW_POINTER | NET | JELLYFISH | Notes | |---|---|---|---|---| | name | ✓ | ✓ | ✓ | Mode selector | | density | ✓ | ✓ | ✓ | Particle count multiplier | | color | ✓ | ✓ | ✓ | Single hex/HSL/CSS color | | colors | ✓ | ✓ | ✓ | Palette override | | colorMode | ✓ | ✓ | ✓ | wave (default) or mixed | | shape | ✓ | ✓ | ✓ | bean default in FOLLOW_POINTER, circle in NET/JELLYFISH | | particleSpeed | ✓ | ✓ | ✓ | Animation speed multiplier | | pointerTrackingSpeed | ✓ | ✓ | ✓ | Cursor-follow/response smoothness | | orientation | ✓ | — | — | Only FOLLOW_POINTER (vertical default) | | interactionRadius | — | — | — | Declared in type, currently not applied in v0.2.1 | | lineDistance | — | — | — | Declared in type, currently not applied in v0.2.1 |

Practical presets

| Goal | Suggested config | |---|---| | Calm ambient hero | JELLYFISH, density: 0.8, pointerTrackingSpeed: 0.015 | | High-energy interactive background | FOLLOW_POINTER, density: 1.2, particleSpeed: 1.3, shape: 'bean' | | Tech/network look | NET, density: 0.9, colorMode: 'mixed', cool blue palette |


API reference

<ParticleCanvas>

| Prop | Type | Default | Description | |---|---|---|---| | width | string \| number | '100%' | Container width | | height | string \| number | '60vh' | Container height | | backgroundColor | string | '#050505' | Background color | | background | BackgroundCanvas | { name: 'NONE' } | Animated background config | | className | string | '' | Additional CSS class | | style | CSSProperties | — | Inline style overrides |

BackgroundCanvas

| Prop | Type | Description | |---|---|---| | name | 'NONE' \| 'FOLLOW_POINTER' \| 'NET' \| 'JELLYFISH' | Background mode | | orientation | 'vertical' \| 'horizontal' \| 'diagonal' | Direction style for FOLLOW_POINTER | | density | number | Particle amount multiplier | | color | string | Single background particle color | | colors | string[] | Background particle palette | | colorMode | 'wave' \| 'mixed' | Palette propagation mode | | shape | 'circle' \| 'square' \| 'bean' | Particle drawing shape | | particleSpeed | number | Background animation speed multiplier | | pointerTrackingSpeed | number | Cursor tracking interpolation factor | | interactionRadius | number | Reserved in type (not applied in v0.2.1) | | lineDistance | number | Reserved in type (not applied in v0.2.1) |

<TextParticleEngine>

| Prop | Type | Default | Description | |---|---|---|---| | text | string | required | Text the particles form | | particleColor | string \| string[] | '255, 255, 255' | RGB string or array of hex colors | | particleSize | number | 1 | Size multiplier | | particleDensity | number | 1 | Particle count multiplier | | particleEase | number | 1 | Return speed multiplier | | isMagnet | boolean | true | Hover attraction effect | | clickMode | 'none' \| 'attract' \| 'repel' | 'none' | Click/tap interaction | | particleShape | 'circle' \| 'square' \| 'bean' | 'circle' | Particle shape | | backgroundColor | string | '#050505' | Canvas background (hex) |

Color note: particleColor accepts 'R, G, B' strings (e.g. '255, 100, 50') or hex strings in an array (e.g. ['#ff0000', '#00ff00']). Alpha is handled internally.


License

MIT