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

@ljhaesler/microbiome

v1.0.6

Published

Microbiome module for the 'Spamalaxy' project

Readme

@ljhaesler/microbiome

A PixiJS v8 visualization for the Spamalaxy project. Renders clusters of soft, gooey "metaball" blobs that orbit the screen, drift apart under repulsion, and respond to click-and-drag.

Installation

npm install @ljhaesler/microbiome

Quick start

import { Microbiome, ColorHandler } from "@ljhaesler/microbiome";

// 1. Set up colours: map association names to one or more colours each.
const colorHandler = new ColorHandler();
colorHandler.setOptions({
	anger: "ff5500, ffaa00",
	jealousy: "00aaff, 0055ff, 00ff00",
});

// 2. Create the app and initialise the Pixi canvas.
const microbiome = new Microbiome(colorHandler);
await microbiome.quickInit();

// 3. Create MetaballSets
const angerSet1 = microbiome.addMetaballSet("anger");
const angerSet2 = microbiome.addMetaballSet("anger");
const jealousySet = microbiome.addMetaballSet("jealousy");

// 4. Populate MetaballSet with Metaballs
// 		the set is populated with as many metaballs as there are colours
angerSet1.addMetaballs({ metaballRadius: 120, metaballRatio: 1.2 });
angerSet2.addMetaballs({ metaballRadius: 200, metaballRatio: 0.8 });
jealousySet.addMetaballs({ metaballRadius: 150, metaballRatio: 1.1 });
// will not work (make a new set instead):
// jealousySet.addMetaballs({ metaballRadius: 150, metaballRatio: 1.1 });

// 5. Drive the animation loop.
microbiome.ticker.add((ticker) => {
	microbiome.tick(ticker.lastTime * 0.001, /* orbitalSpeed */ 0.5);
});

API

Microbiome

Extends pixi.js Application. The entry point: owns the renderer/stage, holds the metaball sets, and advances the animation each frame.

new Microbiome(colorHandler)

| Parameter | Type | Description | | -------------- | -------------- | -------------------------------------------- | | colorHandler | ColorHandler | Provides the colour set for each association |

colorHandler is required. Does not initialise the renderer — call quickInit() first.

await microbiome.quickInit()

Initialises the Pixi application (black background, full-window, antialiased), appends the canvas to document.body, and installs the metaball fusion filter on the stage. Must be called before adding content.

For different init options, call the inherited Application.init() yourself, then apply the filter and mount the canvas manually.

microbiome.addMetaballSet(association)

Creates a MetaballSet, adds it to the stage, and returns it. Its colours are resolved from the ColorHandler.

| Parameter | Type | Description | | ------------- | -------- | -------------------------------------- | | association | string | A key registered in the ColorHandler |

microbiome.metaballSets

Getter. Returns all sets created via addMetaballSet, in creation order.

microbiome.tick(t, orbitalSpeed)

Advances one animation frame. Call this inside your ticker.

| Parameter | Type | Description | | -------------- | -------- | ----------------------------------------------- | | t | number | Elapsed time, drives per-blob skew wobble | | orbitalSpeed | number | Angular speed at which unclicked clusters orbit |

Each frame, every unclicked cluster orbits the screen centre while updateChildren() applies the intra-cluster physics and each blob's skew wobbles from t.


MetaballSet

Extends pixi.js Container. A single cluster of metaballs sharing one colour association. Obtain one via Microbiome.addMetaballSet rather than constructing it directly. The cluster lives in a fixed 128×128 coordinate space that governs centre attraction.

metaballSet.addMetaballs({ metaballRadius, metaballRatio })

Populates the cluster with one Metaball per colour in the association, each smaller than the last, so an association renders as a few nested blobs of graduated size.

| Property | Type | Description | | ---------------- | -------- | ------------------------------------------------------------------------------------------ | | metaballRadius | number | Base radius for the first blob; also used as the physics minDistance | | metaballRatio | number | How quickly blobs shrink: blob i has radius metaballRadius / (metaballRatio * (i + 1)) |

Each blob gets a radial-gradient texture from the association's colour and its own drag listeners.

metaballSet.updateChildren()

Runs one physics step: pairs of blobs closer than minDistance repel, then integration applies centre attraction, friction, position updates, and edge bounces. Called for you by Microbiome.tick.

Properties

| Property | Type | Description | | --------------- | ---------------- | ------------------------------------------------ | | association | string | The colour association key for this cluster | | colors | Color[] | The colour set resolved from the ColorHandler | | renderer | Renderer | The Pixi renderer, used to bake blob textures | | containerSize | number | The cluster's coordinate space (128) | | fillGradients | FillGradient[] | One radial gradient per colour | | rotationSpeed | number | Per-cluster spin applied during orbit | | clicked | boolean | true while pressed; pauses the cluster's orbit |


Metaball

Extends pixi.js Sprite. A single blob, created by MetaballSet.addMetaballs. Spawns at a random point inside its cluster and carries the per-blob animation state: velocity (vx, vy), skew wobble (skewSpeed, skewPhaseX, skewPhaseY), and rotationSpeed.

metaball.addEventListeners()

Enables click-and-drag. While pressed, the blob follows the pointer and its clicked flag excludes it from the physics until released. Called for you by MetaballSet.addMetaballs.


ColorHandler

Extends Map. Maps association names to arrays of pixi.js Color objects. Microbiome uses it to resolve the colours for each cluster.

Re-exported from the @ljhaesler/color-handler package, which @ljhaesler/microbiome depends on. You can import it directly from either package.

| Method | Description | | ----------------------------- | ------------------------------------------------------------------------------ | | setOptions(object) | Register associations and colours together ({ name: "c1, c2", … } or arrays) | | setAssociations(str\|array) | Set the association names (comma-separated string or array) | | setColors(str\|array) | Set the colour sets ("a,b / c,d" string, or array of arrays) | | getColorSet(association) | Return the Color[] for an association | | reorder(str\|array) | Reorder the associations; length must match the number of colour sets | | associations | Getter. The current list of association names |

See the @ljhaesler/color-handler package for full details.


The metaball filter

quickInit() installs a custom WebGL fragment shader (modules/Filters.js) on the stage. It hard-thresholds the accumulated alpha coverage of overlapping blobs — coverage ≥ 0.9 becomes opaque, ≤ 0.88 transparent, with a smooth band between — so separate blobs merge into organic shapes where they overlap while keeping their colour.

Notes & requirements

  • Browser only. Uses window (for resizeTo) and document.body (to mount the canvas).
  • PixiJS v8. Built against pixi.js ^8.19.0, including pixi.js/advanced-blend-modes.
  • You own the ticker. Microbiome does not start its own loop — call tick() each frame.