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

r3f-particle-system

v1.0.3

Published

A declarative particle system for React Three Fiber. It uses an FBO Simulation to provide incremental updates to particles, allowing for an intuitive API with use of forces. **Note**: This package is experimental and may introduce breaking changes in futu

Readme

r3f-particle-system

A declarative particle system for React Three Fiber. It uses an FBO Simulation to provide incremental updates to particles, allowing for an intuitive API with use of forces. Note: This package is experimental and may introduce breaking changes in future releases.

Check out the demo to see it in action! This is just one of many possible configurations for this tool.

Installation

This package relies on the following peer dependencies. You need to have them installed in your project:

| Package | Required Version | |----------------------|------------------| | @react-three/drei | ^9.101.0 | | @react-three/fiber | ^8.15.19 | | react | ^18 | | three | ^0.170.0 |

Install Peer Dependencies

To install all the required peer dependencies for with this package, run the following command:

npm install @react-three/drei@^9.101.0 @react-three/fiber@^8.15.19 react@^18 three@^0.170.0

Install Package

Once peer dependencies are installed, install the package:

npm install r3f-particle-system

Usage

The particle system consists of four main components: ParticleSystem, Emitters, Forces, and Particles. The ParticleSystem acts as a context wrapper and must be included for the system to function. Within it, you can use one Emitter, one Particle, and multiple Forces to define and manipulate the behavior of particles.

Example

<ParticleSystem>
  <BoxEmitter speed={[ 0.8, 1 ]} life={[ 1, 10 ]} />
  <DirectionalForce direction={[ 0, 1, 0 ]} randomAmt={ 0.1 } strength={ 2 } />
  <RotationalForce strength={ 1.5 } />
  <PointParticle 
    shape="circle" 
    color={[ "cyan", "magenta" ]} 
    size={[ 5, 25 ]} 
    alphaFade={[ 0.25, 1 ]} 
  />
</ParticleSystem>

Components

ParticleSystem

The core context provider that manages data across the particle system.

Props:

  • simulationSpace: Determines the coordinate space for particles ("local" | "world")
  • normalizeForces: When true, normalizes the sum of all forces (useful for maintaining predictable speeds).

Example w/ Default Values:

<ParticleSystem 
  simulationSpace="local" 
  normalizeForces={ false } 
/>

Emitters

Emitters are responsible for spawning particles. Only one emitter can be used per system.

BoxEmitter

Spawns particles from within a box-shaped volume.

Props:

  • size: Particle buffer size (e.g., 128 = 16,384 particles).
  • spawnRate: Number of particles spawned per second.
  • life: Particle lifespan or min and max life (life | [min, max]).
  • speed: Particle speed or man and max speed (speed | [min, max]).
  • bounds: Dimensions of the box [x, y, z].

Example w/ Default Values:

<BoxEmitter
  size={ 128 }            
  spawnRate={ 500 }       
  life={[ 1.0, 5.0 ]}     
  speed={[ 0.5, 2.0 ]}    
  bounds={[ 1, 1, 1 ]}  
/>

CurveEmitter

Spawns particles along a curve.

Props:

  • size: Particle buffer size (e.g., 128 = 16,384 particles).
  • spawnRate: Number of particles spawned per second.
  • life: Particle lifespan or min and max life (life | [min, max]).
  • speed: Particle speed or man and max speed (speed | [min, max]).
  • points: Array of control points defining the curve.
  • controlOffset: Smoothness of curve corners.
  • curve: Optional THREE.Curve instance (overrides points).
  • sampleMode: Distribution mode along the curve ("random" | "sequential").
  • isLoop: Whether the curve loops.
  • resolution: How many points make up this curve.
  • randomOffset: Random positional offset for particles.
  • debug: When true shows the curve and control points.

Example w/ Default Values:

<CurveEmitter 
  size={ 128 }                            
  spawnRate={ 500 }                       
  life={[ 1.0, 5.0 ]}                     
  speed={[ 0.5, 2.0 ]}                    
  points={[[ 0, 0, 0 ], [ 0, 1, 0 ]]}   
  controlOffset={ 0.1 }                   
  curve={ null }                          
  sampleMode="random"                   
  isLoop={ false }                        
  resolution={ 100 }                      
  randomOffset={ 0.1 }                    
  debug={ false }                         
/>

CylinderEmitter

Spawns particles within a cylindrical volume.

Props:

  • size: Particle buffer size (e.g., 128 = 16,384 particles).
  • spawnRate: Number of particles spawned per second.
  • life: Particle lifespan or min and max life (life | [min, max]).
  • speed: Particle speed or man and max speed (speed | [min, max]).
  • innerRadius: Inner radius of the cylinder (no particles spawn inside).
  • outerRadius: Outer radius of the cylinder.
  • height: Cylinder height.
  • arc: Angular section of the cylinder (in radians).

Example w/ Default Values:

<CylinderEmitter 
  size={ 128 }          
  spawnRate={ 500 }     
  life={[ 1.0, 5.0 ]}   
  speed={[ 0.5, 2.0 ]}  
  innerRadius={ 0.0 },  
  outerRadius={ 1.0 },  
  height={ 0.0 },       
  arc={ Math.PI * 2 }   
/>

MeshEmitter

Spawns particles from the surface of a mesh.

Props:

  • size: Particle buffer size (e.g., 128 = 16,384 particles).
  • spawnRate: Number of particles spawned per second.
  • life: Particle lifespan or min and max life (life | [min, max]).
  • speed: Particle speed or man and max speed (speed | [min, max]).
  • sampleMode: Determines particle spawn positions ("random" | "sequential" | "shuffled").
  • debug: If true, renders the input mesh for visualization.

Note: The source mesh must be a child of this emitter.

Example w/ Default Values:

<MeshEmitter
  size={ 128 }           
  spawnRate={ 500 }      
  life={[ 1.0, 5.0 ]}    
  speed={[ 0.5, 2.0 ]}   
  sampleMode="random", 
  debug={ false }        
>
  <mesh>
    <sphereGeometry>
    <meshBasicMaterial>
  </mesh>
</MeshEmitter>

SphereEmitter

Spawns particles within a spherical volume.

Props:

  • size: Particle buffer size (e.g., 128 = 16,384 particles).
  • spawnRate: Number of particles spawned per second.
  • life: Particle lifespan or min and max life (life | [min, max]).
  • speed: Particle speed or man and max speed (speed | [min, max]).
  • radius: Radius of the sphere.
  • surface: If true, particles conform to the sphere's surface.

Example w/ Default Values:

<SphereEmitter 
  size={ 128 }        
  spawnRate={ 500 }   
  life={[ 1.0, 5.0 ]} 
  speed={[ 0.5, 2.0 ]}
  radius={ 1 },       
  surface={ false },  
/>

Forces

Forces affect the movement and behavior of particles. Multiple forces can be applied simultaneously.

DirectionalForce

Applies a constant directional force.

Props:

  • direction: Force direction vector ([x, y, z]).
  • randomAmt: Random deviation from the base direction.
  • strength: Strength of the force.

Example w/ Default Values:

<DirectionalForce
  direction={[ 0, 1, 0 ]},       
  randomAmt={ 0 },            
  strength={ 1 }                 
/>

RotationalForce

Applies rotational force around a center.

Props:

  • center: Center point of rotation.
  • axis: Rotation axis ("xy" | "xz" | "yz").
  • strength: Strength of the force.

Example w/ Default Values:

<RotationalForce
  axis="xyz",     
  seed="random",  
  period={ 1 },     
  strength={ 1 }    
/>

NoiseForce

Applies a curl noise force to particles.

Props:

  • axis: Which axes are affected by the force ("xyz" | "xy" | "xz" | "yz").
  • seed: Seed position ([x, y, z] | "random").
  • period: The period of the noise.
  • strength: Strength of the force.

Example w/ Default Values:

<NoiseForce
    axis="xyz",        
    seed="random",     
    period={ 1 },        
    strength={ 1 }       
/>

CurveTangentForce

Applies a force along the tangent of a curve. Only has Eefect when using CurveEmitter.

Props:

  • direction: The direction of the force along the curve (1 | -1)
  • randomAmt: Random deviation from the base direction.
  • strength: Strength of the force.

Example w/ Default Values:

<CurveTangentForce
  direction={ 1 },            
  randomAmt={ 0.25 },         
  strength={ 1 }              
/>

NormalForce

Applies a force perpendicular to a surface. Only has effect when using the MeshEmitter.

Props:

  • strength: Strength of the rotation.

Example w/ Default Values:

<NormalForce   
  strength={ 1 }    
/>

PointForce

Dynamically applies a force from a point source up to an effective threshold.

Props:

  • position: The center positions of the force.
  • direction: The direction of the force relative to the center position ("towards" | "away").
  • axis: Which axes are affected by the force ("xyz" | "xy" | "xz" | "yz").
  • effectiveDist: The extents this force affects particles around its center.
  • strength: Strength of the rotation.
  • returnForce: Force particles back to their original position when outside effectiveDist.
  • returnForce: The strength of the return force.

Example w/ Default Values:

<PointForce
  position={[ 0, 0, 0 ]}, 
  direction="towards",    
  axis="xyz",             
  effectiveDist={ 1 },      
  strength={ 1 },           
  returnForce={ true },     
  returnStrength={ 1 }      
/>

Particles

PointParticle

Defines individual particles rendered as points.

Props:

  • shape: Particle shape ("circle" | "square" | "softCircle" | "point").
  • color: Particle color (single value or array for gradients).
  • colorMode: Determines how colors are applied ("overLife" | "random").
  • size: Particle size or range (size | [min, max]).
  • alphaFade: Fade-in and fade-out alpha values.
  • depthWrite: depthWrite value for the particles.
  • depthTest: depthTest value for the particles.
  • blending: blending value for the particles.

Example w/ Default Values:

<PointParticle
  shape="circle"                   
  color="blue"                     
  colorMode="overLife",            
  size={ 50 }                        
  alphaFade={ 1 }                    
  depthWrite={ false },              
  depthTest={ true },                
  blending={ THREE.NormalBlending }, 
/>

Imperative API & Particle Bursts

Refs of ParticleSystem can be used to expose it's imperative API. Available methods are stop(), start(), and createBurst(). After stopping the system, createBurst(numParticles) can be used to create a burst of particles at runtime.

Example Usage:


// create ref for particle system
const systemRef = useRef();

// pause the spawning of particles
useEffect(() => {
  systemRef.current.pause(); 
}, []);

// create burst of 2000 particles using 'onpointerdown' event
useEffect(() => {
  const burst = () => systemRef.current.createBurst(2000);
  window.addEventListener('pointerdown', burst);
  return () => window.removeEventListener('pointerdown', burst);
}, []);

return (
  <ParticleSystem ref={ systemRef }>
   ...
  </ParticleSystem>
);

Roadmap

Planned features for future releases:

  • MeshParticle Component: Instanced meshes as particles for more advanced visuals.
  • Color Sampling: Allow particles to inherit colors from meshes or textures.
  • Lighting: Allow particles to be affected by scene lighting.
  • Scene Collisions: Allow for particle collisions with scene using depth buffer
  • Strength over time: Option for strength over time to give move control with forces.

License

MIT License