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

@anarkisti/igyb

v0.5.0

Published

Tree-shakeable repeating & generative backgrounds — geometric tiles and WebGL generative art, framework-agnostic with a Svelte wrapper.

Readme

@anarkisti/igyb

Tree-shakeable repeating & generative backgrounds — geometric tiles and WebGL generative art. A framework-agnostic core (Canvas2D + WebGL) with a thin Svelte wrapper.

Live playground →

yarn add @anarkisti/igyb

Vanilla

import { flowField } from '@anarkisti/igyb/core';

const bg = flowField(document.querySelector('#hero')!, { theme: 'neon', interactive: true });
bg.start();
// bg.update({ theme: 'terminal' });  // live re-theme
// bg.destroy();

Svelte

<script>
	import Background from '@anarkisti/igyb/svelte';
	import { plasma } from '@anarkisti/igyb/core';
</script>

<div style="height: 100vh">
	<Background pattern={plasma} options={{ theme: 'ink', interactive: true }} />
</div>

Web component (any framework)

<igyb-background> resolves a pattern by name from the registry — drop it into plain HTML, React, Vue, anything:

import { register } from '@anarkisti/igyb/element';
register(); // defines <igyb-background> once
<igyb-background
	pattern="gradientMesh"
	theme="sunset"
	interactive
	style="display:block; inline-size:100%; block-size:100vh"
></igyb-background>

React

Use <igyb-background> above, or this ~20-line wrapper that takes a tree-shakeable factory:

import { useEffect, useRef } from 'react';
import type { AnyBackgroundFactory, BaseOptions } from '@anarkisti/igyb/core';

export function Background({
	pattern,
	options,
	paused
}: {
	pattern: AnyBackgroundFactory;
	options?: BaseOptions & Record<string, unknown>;
	paused?: boolean;
}) {
	const host = useRef<HTMLDivElement>(null);
	const bg = useRef<ReturnType<AnyBackgroundFactory>>();
	useEffect(() => {
		bg.current = pattern(host.current!, options);
		if (!paused) bg.current.start();
		return () => bg.current?.destroy();
	}, [pattern]); // eslint-disable-line react-hooks/exhaustive-deps
	useEffect(() => bg.current?.update(options ?? {}), [options]);
	useEffect(() => (paused ? bg.current?.stop() : bg.current?.start()), [paused]);
	return <div ref={host} style={{ position: 'relative', width: '100%', height: '100%' }} />;
}

Patterns

| Pattern | Import (@anarkisti/igyb/core) | Renderer | Category | | ------------- | ------------------------------- | -------- | ---------- | | Flow field | flowField | WebGL | Generative | | Plasma | plasma | WebGL | Generative | | Gradient mesh | gradientMesh | WebGL | Generative | | Aurora | aurora | WebGL | Generative | | Metaballs | metaballs | WebGL | Generative | | Voronoi | voronoi | WebGL | Generative | | Particles | particles | Canvas2D | Generative | | Ripple | ripple | Canvas2D | Generative | | Matrix rain | matrixRain | Canvas2D | Generative | | Starfield | starfield | Canvas2D | Generative | | Truchet | truchet | Canvas2D | Geometric | | Hex | hex | Canvas2D | Geometric | | Isometric | iso | Canvas2D | Geometric | | Dot grid | dotGrid | Canvas2D | Geometric | | Wave lines | waveLines | Canvas2D | Geometric | | Low poly | lowPoly | Canvas2D | Geometric | | Glyph tile | glyphTile | Canvas2D | Geometric |

Overlays for layering: grain, vignette, scanlines, spotlight.

Deep imports (@anarkisti/igyb/patterns/flow-field) keep bundles minimal even without tree-shaking. Every pattern also takes theme, animate, speed, interactive (true | 'fine'), pointerSource, pointerSmoothing, themeTransition, reducedMotion, autoPause and dpr. Interactive patterns track multitouch (pointer.points); the loop auto-pauses while the tab is hidden or the host scrolls offscreen. Set themeTransition (seconds) to crossfade palettes on a theme change, and pattern authors can read env.scroll (window scroll progress) for scroll-linked effects. Themes: ink (default), neon, pastel, terminal, mono, paper, halo, sunset, ocean, cyberpunk, forest, or a custom Palette.

Composing layers

Stack patterns into one background with per-layer opacity and blend — WebGL and Canvas2D mix freely, since each layer keeps its own canvas:

import { layers, aurora, particles, grain, vignette } from '@anarkisti/igyb/core';

const bg = layers(
	[
		{ pattern: aurora },
		{ pattern: particles, blend: 'screen', opacity: 0.6 },
		{ pattern: grain, blend: 'overlay', opacity: 0.5 },
		{ pattern: vignette, options: { animate: false } }
	],
	{ theme: 'sunset' } // shared across every layer
)(document.querySelector('#hero')!);
bg.start();

const poster = bg.capture(); // data URL — a static first-frame for SSR/LCP

bg.capture() works on any background (single or layered). For a gallery or a randomize button, @anarkisti/igyb/registry lists every pattern with metadata; @anarkisti/igyb/element ships an <igyb-background> custom element.

Theming from CSS variables

For token-driven apps, read the palette straight from CSS custom properties and pass theme as a thunk. On a light/dark flip, call bg.refresh() — it re-invokes the thunk and repaints in place, no teardown:

import { glyphTile, paletteFromCSS } from '@anarkisti/igyb/core';

const map = { bg: '--surface', fg: '--ink', accents: ['--accent'] };
const bg = glyphTile(el, { theme: () => paletteFromCSS(map) });
bg.start();

// when your theme toggles (after the new tokens land on the element):
bg.refresh();

Drawing your own glyph/marks? The glyphTile callback receives the resolved palette, and @anarkisti/igyb/core exports small color helpers so you don't re-roll them:

import { lighten, mix, toRgb } from '@anarkisti/igyb/core';

glyphTile(el, {
	glyph(ctx, size, i, { palette, highlight }) {
		ctx.strokeStyle = mix(palette.fg, lighten(palette.fg, 0.8), highlight); // reacts to the pointer
		ctx.strokeRect(-size / 4, -size / 4, size / 2, size / 2);
	}
});

toRgb / toRgbString, mix, lighten, darken accept hex or rgb() strings.

Authoring

import { defineCanvas2D } from '@anarkisti/igyb/core';

export const stripes = defineCanvas2D<{ width?: number }>({
	defaults: { width: 20 },
	frame({ ctx, surface, palette, time, options }) {
		/* draw one frame */
	}
});

defineWebGL is the same shape with a WebGL2 gl context. Cache resources in env.state.