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

@commercengine/shaders

v0.1.0

Published

Commerce Engine's brand artwork: Paper's Warp shader in the brand palette, with named looks, a framework-agnostic mount and instant stills

Readme

@commercengine/shaders

Commerce Engine's brand artwork: Paper's Warp shader in the brand palette, with named looks, a framework-agnostic mount and a still per look that paints instantly while the shader comes up.

  • Looks, not featuresaurora, tide, meadow, lagoon; each is a set of colours and warp geometry any surface can ask for.
  • One mount for every frameworkmountShader(host, options) returns a handle; Angular, React, Vue, Svelte and plain scripts are each a few lines over it.
  • No blank frame — the host paints a 144×82 still of the look from its first paint, the canvas mounts invisible and fades in after its first render. Without WebGL 2, the still is what a viewer sees.
  • Respectful by default — holds the frame under prefers-reduced-motion, pauses while the tab is hidden or the host is off-screen (Paper), survives a lost WebGL context.

Install

pnpm add @commercengine/shaders

@paper-design/shaders comes with it, pinned: the looks are written against its uniforms.

Use

import { mountShader } from "@commercengine/shaders";

const artwork = mountShader(document.querySelector("#artwork"), { preset: "aurora" });

// later
artwork.setPreset("tide");
artwork.setPaused(true);
artwork.dispose();

The host is any block element with a size; the mount fills it. Paper makes the host position: relative unless it is positioned already, so a host that is itself position: absolute; inset: 0 inside a parent works. Paint the brand's Jungle (#002e27) under it if the host can ever be seen before the still.

Options

| Option | Default | What it does | | --- | --- | --- | | preset | "aurora" | The look. | | settings | {} | Any of the look's values, over the preset's (see Tuning). | | paused | false | Hold the frame. | | still | true | Paint the look's still on the host until the canvas is ready. | | maxPixelCount | 1_200_000 | Physical pixels the shader renders at most; larger hosts upscale. | | startFrame | 12_000 | Where Paper's clock starts; the stills are taken here. | | onError | — | Called once if the shader cannot mount (no WebGL 2, compile failure). |

Handle

setPreset, setSettings, setPaused, dispose, plus reducedMotion (the viewer's preference), onReducedMotionChange(listener) for a pause control that wants to disable itself, and settings (the look currently playing, resolved).

In a framework

// React
useEffect(() => {
  const artwork = mountShader(ref.current, { preset });
  return () => artwork.dispose();
}, []);
useEffect(() => artwork?.setPreset(preset), [preset]);
// Angular (signals)
private readonly handle = mountShader(inject(ElementRef).nativeElement, { preset: this.preset() });
constructor() {
  effect(() => this.handle.setPreset(this.preset()));
  inject(DestroyRef).onDestroy(() => this.handle.dispose());
}

Tuning a look

import { resolveShaderSettings, shaderPresets, shaderShapes } from "@commercengine/shaders";

mountShader(host, { preset: "aurora", settings: { rotation: 30, shape: "stripes" } });

Every value of a look is a knob: the five colors (dark to light; the fourth is the highlight, the fifth what the blend returns to), proportion, softness, distortion, swirl, swirlIterations (the one that costs GPU), shape (checks / stripes / edge), shapeScale, scale, rotation, speed. When a tuned look is worth keeping, paste resolveShaderSettings(preset, overrides) into src/settings.ts as a preset and regenerate the stills.

Stills

src/stills.ts is generated: one frame of each look at its start frame, captured from the shader itself in headless Chrome at a desktop viewport and scaled to 144×82 WebP (about 2 KB each).

pnpm build      # the capture page loads dist/still-page.iife.js
pnpm stills     # CHROME_PATH / PROBE_PORT override the defaults
pnpm build      # the library carries the new stills

Development

pnpm dev        # tsdown --watch
pnpm test       # vitest
pnpm typecheck

Releases go through changesets from the repository root — see RELEASE.md.