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

codys-cube

v0.3.1

Published

human-written description forthcoming, this is my cube.

Readme

codys-cube

Draft README (AI-drafted). Human editing pending — see DESCRIPTION.draft.md. The repo/npm description is intentionally a placeholder for now.

A dependency-free, content-agnostic 3D cube. It handles the feel — drag to orbit with damped momentum, idle zero-gravity drift, scroll/pinch zoom, and press-to-focus — and hands you callbacks. What lives on the six faces is entirely up to you: terminals, articles, images, iframes, canvases. Zero dependencies, no build step, ~9 KB of vanilla ES modules.

Extracted from cmux3d (a rotatable cube of six live terminals) so that project and hergenroeder.me (a portfolio whose homepage is the cube) share one source of truth instead of a fork. Fix a bug here, both get it.

The idea

The controller never touches your content. It only:

  1. reads pointer/wheel input over a viewport,
  2. writes --rx, --ry, --scale custom properties on a rig,
  3. tells you onFocus(face) / onMove(rotation) / onRelease().

Your CSS turns those custom properties into a transform; your app decides what focusing a face means (open a terminal, flatten into an article, zoom a photo). That single seam is the whole design.

Install

npm install codys-cube

Or, buildless in the browser via a CDN (no bundler, no npm needed at runtime):

import { SpaceController } from 'https://esm.sh/codys-cube';
// or pin: 'https://esm.sh/[email protected]'

Or as a git submodule (what hergenroeder.me does, to keep same-origin + buildless):

git submodule add https://github.com/codyhxyz/codys-cube vendor/codys-cube
# then import from '/vendor/codys-cube/src/space.js'

Quick start

HTML — a rig of face elements inside a viewport. Each face carries data-face:

<div class="viewport" id="viewport">
  <div class="rig" id="rig">
    <section class="panel" data-face="0">…front…</section>
    <section class="panel" data-face="1">…right…</section>
    <!-- 2 back · 3 left · 4 top · 5 bottom -->
  </div>
</div>

CSS — the ~20 lines that turn the controller's custom properties into a cube:

.viewport { position: fixed; inset: 0; display: grid; place-items: center;
            perspective: 3200px; touch-action: none; }
.rig { position: relative; width: var(--cube, 70vmin); height: var(--cube, 70vmin);
       transform: rotateX(var(--rx)) rotateY(var(--ry)) scale(var(--scale, 1));
       transform-style: preserve-3d; }
.panel { position: absolute; inset: 0; backface-visibility: hidden; }
.panel[data-face="0"] { transform: translateZ(calc(var(--cube, 70vmin) / 2)); }
.panel[data-face="1"] { transform: rotateY(90deg)  translateZ(calc(var(--cube, 70vmin) / 2)); }
.panel[data-face="2"] { transform: rotateY(180deg) translateZ(calc(var(--cube, 70vmin) / 2)); }
.panel[data-face="3"] { transform: rotateY(-90deg) translateZ(calc(var(--cube, 70vmin) / 2)); }
.panel[data-face="4"] { transform: rotateX(90deg)  translateZ(calc(var(--cube, 70vmin) / 2)); }
.panel[data-face="5"] { transform: rotateX(-90deg) translateZ(calc(var(--cube, 70vmin) / 2)); }

JS:

import { SpaceController } from 'codys-cube';

const space = new SpaceController({
  viewport: document.getElementById('viewport'),
  rig: document.getElementById('rig'),
  // the angle the cube tweens to when each face is focused:
  faces: [
    { face: 0, view: { x: -8, y: 0 } },
    { face: 1, view: { x: -8, y: -90 } },
    { face: 2, view: { x: -8, y: 180 } },
    { face: 3, view: { x: -8, y: 90 } },
    { face: 4, view: { x: -96, y: 0 } },
    { face: 5, view: { x: 82, y: 0 } },
  ],
  onFocus: (face) => {/* open / flatten / zoom face */},
  onRelease: () => {/* return to the cube */},
  onMove: (rotation) => {/* e.g. drive a backdrop */},
});

space.bind();

Drag orbits with momentum; releasing throws it. A press without a drag (>4px) focuses the face under the pointer. Scroll zooms; two-finger pinch zooms on touch. Call space.focus(n) / space.release() yourself for a nav rail or deep links, and space.orbitStep(dx, dy) for keyboard arrows.

API

| Member | Purpose | | --- | --- | | new SpaceController(options) | see options below | | .bind() | attach listeners, start the idle-drift loop; returns this | | .focus(face) | tween to a face's view and fire onFocus | | .release() | leave focus, reset zoom, resume drift, fire onRelease | | .orbitStep(dx, dy) | nudge rotation (keyboard), no momentum | | .setView(face, {x, y}) | (re)register a face's focus angle |

Options: viewport, rig, faces, onFocus, onMove, onRelease, zoomMin (0.72), zoomMax (1.42), focusZoom (1.08), panelSelector (.panel).

Respects prefers-reduced-motion: no idle drift, no throw-momentum, instant focus.

Optional backdrop shader

import { startShader } from 'codys-cube/shader';
const bg = startShader(document.getElementById('bg-canvas')); // full-viewport <canvas>
space.onMove = (r) => bg.setOrbit(r);
// bg.setFocus(face) on focus/release

An opinionated dark WebGL field (noise mist + receding grid floor + beam + cursor glow) that reacts to orbit and focus. It's a separate export on purpose — great for an instrument/terminal aesthetic, wrong for a light editorial page. Leave it out and you pay nothing for it.

Consumers

  • cmux3d — six live terminals on the faces.
  • hergenroeder.me — a portfolio; faces flatten into articles on focus.

License

MIT © Cody Hergenroeder