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/galaxy

v2.4.15

Published

Galaxy module for the 'Spamalaxy' project

Readme

@ljhaesler/galaxy

A PixiJS-based galaxy visualization for the Spamalaxy project. Renders users as orbiting particle systems with configurable color associations.

Installation

npm install @ljhaesler/galaxy

Usage

import { ColorHandler, Galaxy } from "@ljhaesler/galaxy";

const colors = new ColorHandler();
colors.setOptions({
	red: "crimson, salmon",
	blue: "dodgerblue, lightblue",
});

const galaxy = new Galaxy(colors);
await galaxy.quickInit();

// modify the density of the galaxy
galaxy.density = 0.5;

// add an orbiting user system
galaxy.addUser({
	association: "red",
	particleSize: 2,
	particleQuantity: 250,
	centerBias: 4,
});

// add ambient background dust
galaxy.addEmptyUsers({ particleQuantity: 100000, particleSize: 1 });

galaxy.ticker.add((ticker) => {
	galaxy.tick(
		ticker.lastTime * 0.0001,
		ticker.lastTime * 0.00007,
		20000,
		30000,
	);
});

API

ColorHandler

Extends Map. Maps association strings to arrays of pixi.js Color objects.

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

new ColorHandler()

Creates an empty ColorHandler.

colorHandler.setOptions(options)

The primary way to configure a ColorHandler. Sets both colors and associations from a single object.

colors.setOptions({
	groupA: "red, coral", // comma-separated color string
	groupB: ["#00f", "dodgerblue"], // or an array of color values
});

colorHandler.setColors(colorSets)

Set colors independently from associations.

  • String — color sets separated by /, colors within a set separated by ,:
    colors.setColors("red, coral / dodgerblue, lightblue");
  • Array — array of arrays of color values:
    colors.setColors([
    	["red", "coral"],
    	["dodgerblue", "lightblue"],
    ]);

colorHandler.setAssociations(associations)

Set association keys independently from colors.

  • String — comma-separated: 'groupA, groupB'
  • Array['groupA', 'groupB']

The number of associations must match the number of color sets for the map to sync.

colorHandler.getColorSet(association)

Returns the array of pixi.js Color objects for the given association key.

const reds = colors.getColorSet("red"); // Color[]

colorHandler.reorder(options)

Reorders the internal map entries. Accepts the same formats as setAssociations. The provided list must contain every existing association key.

This affects spawn sectors in Galaxy — the first association in the map spawns closest to the center, so reordering changes which group appears where.

colors.setOptions({
	groupA: "red, coral",
	groupB: "dodgerblue, lightblue",
	groupC: "lime, green",
});

colors.associations; // ['groupA', 'groupB', 'groupC']

colors.reorder("groupC, groupA, groupB");

colors.associations; // ['groupC', 'groupA', 'groupB']

Also accepts an array:

colors.reorder(["groupC", "groupA", "groupB"]);

colorHandler.associations

Getter. Returns the current array of association keys.

colors.associations; // ['groupA', 'groupB']

Galaxy

Extends pixi.js Application. Manages a collection of UserSystem instances and animates them in orbiting paths.

new Galaxy(colorHandler)

| Parameter | Type | Description | | -------------- | -------------- | ------------------------------------ | | colorHandler | ColorHandler | Configured color map for user groups |

await galaxy.quickInit()

Initializes the PixiJS application (black background, full-window, antialiased), appends the canvas to document.body, and sets galaxy.center. Must be called before addUser().

galaxy.addUser(options)

Creates a UserSystem, adds it to the galaxy, and returns it. Keep the returned handle if you want to remove that specific user later with removeUser(). Spawn position is determined automatically based on the association's order in the ColorHandler.

Colors and spawn order are read live from the ColorHandler on each call, so mutating or reordering it (e.g. setOptions, reorder) is picked up automatically — no manual sync step. Throws if association doesn't match any key in the ColorHandler.

| Option | Type | Description | | ------------------ | -------- | ---------------------------------------------------------------- | | association | string | Must match a key in the ColorHandler | | particleSize | number | Width/height of each particle square in pixels | | particleQuantity | number | Number of particles in the system | | centerBias | number | Spread of particles within the system. Higher = more center-bias |

const user = galaxy.addUser({
	association: "red",
	particleSize: 3,
	particleQuantity: 80,
	centerBias: 1.5,
});
// ...later
galaxy.removeUser(user);

galaxy.addEmptyUsers(options)

Adds a single EmptyUserSystem overlay to the galaxy — a batch of loose particles that fill out the background. Unlike addUser, whose particles orbit together as one rigid system, each empty-user particle orbits individually, giving a scattered, ambient "dust" effect.

Colors and spawn order are read live from the ColorHandler, the same as addUser. This method does not return a handle; the whole overlay is cleared via destroyUsers().

| Option | Type | Description | | ------------------ | -------------- | ----------------------------------------------------------------------------------------- | | particleQuantity | number | Number of particles in the overlay | | particleSize | number | Width/height of each particle square in pixels | | association | string | Optional. Association for every particle. If omitted, each particle picks one at random | | colorHandler | ColorHandler | Optional. A separate handler for these particles. Defaults to the galaxy's own handler |

// 500 particles, random associations drawn from the galaxy's ColorHandler
galaxy.addEmptyUsers({ particleQuantity: 500, particleSize: 1 });

// or pin every particle to one association
galaxy.addEmptyUsers({
	particleQuantity: 200,
	particleSize: 1,
	association: "red",
});

galaxy.removeUser(user)

Removes a single UserSystem (the handle returned by addUser()) from the galaxy and destroys it. Safe to call with a user that isn't in the galaxy — it's a no-op.

galaxy.destroyUsers()

Destroys every UserSystem currently in the galaxy and removes them from the stage. Safe to call when there are no users. Useful for resetting the visualization before repopulating it.

galaxy.density

number, default 1. Scales how far users spawn from the center — the spawn offset produced by the association's sector is multiplied by density. Lower values pull the whole galaxy toward the center; higher values push it outward.

galaxy.density = 0.6; // more compact galaxy

galaxy.tick(t1, t2, phaseOffset1, phaseOffset2)

Advances the orbit animation. Call this inside your PixiJS ticker.

| Parameter | Type | Description | | -------------- | -------- | ----------------------------------------- | | t1 | number | Primary time value, drives x-axis orbit | | t2 | number | Secondary time value, drives y-axis orbit | | phaseOffset1 | number | Phase shift applied to x-axis per-user | | phaseOffset2 | number | Phase shift applied to y-axis per-user |

Varying t1/t2 rates and phaseOffset values produces different orbital shapes (circular, elliptical, Lissajous-style).