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

gloop-sim

v1.0.2

Published

A particle swarm simulation and rendering library for running in the browser.

Readme

Gloop

Gloop is a TypeScript library for simulating swarms of particles in the browser. You could also call it a browser-based DEM simulator. It comes with some predefined physics models for the swarm, and you can define your own. The built-in models run both on the CPU and on the GPU via WebGPU, but implementing GPU support is optional for custom models.

The library also proves a declarative rendering API based on three.js for visualizing the simulation. It's designed to accommodate custom models and logic, so you can render things other than the particles themselves, like forces, velocities, fields or whatever else you can think of.

The documentation website has a live lab where you can try out the capabilities of Gloop without writing any code.

Installation

The package is published on npm as gloop-sim, with three as a required peer dependency. If you use pnpm, you can install the library like this:

pnpm add gloop-sim [email protected]

Quick Start

Here's a swarm of three point masses connected to each other by springs, simulated on the CPU:

import { gloop } from "gloop-sim";

const swarm = await gloop.swarm({
  particleCount: 3,
  initializer: gloop.initializer.fixed({
    positions: [
      [0, 0, 0],
      [1.5, 0, 0],
      [0, 1, 0],
    ],
    velocities: [
      [0, 0, 0],
      [0, 0, 0],
      [0, 0, 0],
    ],
  }),
  model: gloop.model.elasticNetwork({
    masses: [1, 1, 1],
    connections: [
      { between: [0, 1], restLength: 1 },
      { between: [0, 2], restLength: 1 },
      { between: [1, 2], restLength: Math.SQRT2 },
    ],
    stiffness: 40,
    springDamping: 1.5,
  }),
  integrator: gloop.integrator.semiImplicitEuler(),
  backend: gloop.backend.cpu(),
});

To step this simulation forward, you call advance with the desired time step in seconds. snapshot returns a copy of the swarm's state for inspection/visualization.

for (let step = 0; step < 30; step++) {
  swarm.advance({ time: 1 / 60 });
}

const state = await swarm.snapshot();
console.log(state.time, state.particles.positions);

Replacing gloop.backend.cpu() with gloop.backend.gpu() runs the same simulation on the GPU.

Simulation components

A swarm is built from four pluggable pieces:

| | | | ---------------- | --------------------------------------------------------------------------------------- | | Initializers | gloop.initializer provides the initial positions and velocities. | | Models | gloop.model defines the forces acting on the particles. | | Integrators | gloop.integrator advances the particle states in time. | | Backends | gloop.backend runs the computation. cpu and gpu are currently supported. |

Rendering

gloop-sim/render visualizes the swarm with three.js. You first need to have an HTML canvas element to render something onto it.

const canvas = document.createElement("canvas");
document.body.append(canvas);

Then, you can create a stage which will visualize the swarm.

import { view } from "gloop-sim/render";

const stage = await view.stage({
  canvas,
  // Currently only the GPU backend is supported for rendering.
  backend: view.backend.gpu(),
  clear: "#07090B",
  pixelRatio: Math.min(devicePixelRatio, 2),
});

Using stage.observe(swarm) you create a visualization for a specific swarm, which we refer to as a "scene". A scene has a fluent API for configuring the visualization.

In this case, we just want to visualize the particles as points of a specific color.

const scene = stage.observe(swarm).layers([
  view.layer.particles({
    from: view.sources.particles(),
    shape: "point",
    color: "#B8D8D8",
  }),
]);

Finally, we use requestAnimationFrame to animate the swarm in real-time. As before, you advance the simulation using swarm.advance. If you also want to render the new swarm state every time, you can call stage.render(scene) after every step.

function frame(): void {
  swarm.advance({ time: 1 / 60 });
  void stage.render(scene);
  requestAnimationFrame(frame);
}
requestAnimationFrame(frame);

Documentation

| | | | ------------------------------------------------------------------------- | ----------------------------------------------------- | | Getting started | Installation, a first swarm, switching to the GPU | | Core concepts | Swarms, state and snapshots, and the pluggable pieces | | Rendering | Drawing a swarm with three.js | | API reference | Every exported function and type |

Development

Prerequisites:

  • Node.js >= 20 with pnpm
  • uv (for building the docs site via uvx zensical)
  • A browser with WebGPU (for the lab and the GPU tests)

Get set up:

git clone https://gitlab.com/zurabm/gloop.git
cd gloop
pnpm install

Common tasks:

pnpm dev            # run the lab locally
pnpm test           # run the unit tests (vitest)
pnpm test:webgpu    # run the GPU tests in a browser
pnpm test:coverage  # unit tests with coverage
pnpm bench          # benchmark both backends, report in generated/bench/
pnpm check          # lint, spellcheck, typecheck, tests, build
pnpm docs:serve     # serve the docs site

Benchmarks

pnpm bench

This opens Chromium with WebGPU enabled and runs a set of benchmarks. The run is archived to generated/bench/runs/, and the report is written to generated/bench/report.html with a text summary in generated/bench/summary.md.

To compare two archived runs, rebuild the report with one as the baseline:

pnpm bench:report --run generated/bench/runs/<new>.json --baseline generated/bench/runs/<old>.json

See CONTRIBUTING.md for the workflow and code style.

License

MIT, see LICENSE.