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

chogui-three

v0.2.0

Published

Framework-agnostic 3D game-device engine (dice, spintop, board) that settles physics/tween animations onto a predetermined outcome. The three.js companion to chogui; consumed lazily.

Readme

chogui-three

The three.js companion to chogui — a framework-agnostic, vanilla-TS 3D game-device engine that settles physics/tween animations onto a predetermined outcome. The value is decided first (in the host's story engine); the 3D only animates toward it, so the displayed result is correct by construction and every device degrades gracefully when WebGL is unavailable.

Consumed lazily

The engine is reached only through a dynamic import() (in chogui's use3DDevice hook), so the heavier scene/physics modules — and their three / cannon-es deps — stay out of any host's SSR and main bundle. The pure tween + asset-path helpers carry no 3D dependency.

const { containerRef, failed } = use3DDevice((mod, container) => {
  const stage = new mod.Stage(container, /* … */);
  const device = mod.createDevice("spintop", { value, actions /* … */ });
  stage.add(device);
  stage.settle();
  return stage; // a Disposable — disposed on unmount / fallback
}, [value]);
// `failed` flips on load/render error → render a non-3D fallback that still
// performs the device's function (show the label / select the choice).

Stage

Stage owns one three scene/camera/lights/renderer + an rAF loop, an on-demand cannon-es physics world, a device registry, IntersectionObserver pause/resume, raycast picking for interactive devices, and settle detection. Mount devices with add(device); settle(cb) runs to rest, showImmediately() skips the animation (the prefers-reduced-motion / sandbox path); dispose() tears everything down.

Device contract

A device implements Device (mount/update/settle/orientToOutcome/dispose, optional onSelect). Use it one of two ways:

  • Directlynew SpinTopDevice(props) / new BoardDevice(props), then stage.add(device). This is what chogui's tags do.
  • Through the string registry (opt-in) — registerDevice(kind, factory) then createDevice(kind, props); also hasDevice(kind) / listDeviceKinds().

The barrel has no side effects on import — devices are not auto-registered, so the package stays tree-shakeable (sideEffects: false) and a consumer pulls in only the devices it uses. (This mirrors chogui, which also composes packs explicitly rather than registering on import.)

Built-in devices:

  • spintop — an N-sided spinning top (teetotum) on cannon-es. Spins upright, topples on a random axis, and settles. The tumble is decorative; resolveSegmentIndex maps the resolved value to a face index and the story conveys the result. Faces show author-supplied labels (or face numbers).
  • board — a grid of clickable cells with a piece that tweens to a target cell (no physics). Layouts: ring / half / track (defaultLayout picks ring). onSelect(i) reports the chosen cell for choice routing.

Assets

Devices load most assets (surface .webp textures, hit .mp3 sounds, the pawn piece) via bundler ?url imports, so a Vite host resolves and serves them automatically. The dice device additionally fetches its theme textures and sounds at runtime from a served directory, resolved by resolveAssetPath(): an explicit assetPath prop → DEFAULT_ASSET_PATH (/assets/chogui-three/) → CDN_ASSET_PATH (jsDelivr) with preferCdn.

Vendor the served assets into a host with the package-owned script (postinstall is a good home):

node node_modules/chogui-three/scripts/copy-assets.mjs            # → public/assets/chogui-three/
node node_modules/chogui-three/scripts/copy-assets.mjs --dest static/chogui  # custom dest

Hosts that skip the copy can rely on the CDN fallback instead.

Dice (vendored engine)

The MIT dice-box-threejs source is vendored under src/dice-box/ (TypeScript now), wrapped by DiceDevice on the Device contract — the [dice] tag runs on this engine; the upstream @3d-dice/dice-box-threejs dependency is gone. Remaining roadmap: a 2-faced coin riding the die as a d2 face.

License & attribution

This package vendors and adapts dice-box-threejs (MIT) and bundles a CC0 coin model — see THIRD_PARTY_NOTICES.md. package.json declares license: MIT and files; the formal top-level LICENSE text and the private flag flip land with the coordinated publish (the publishable-story-tag-library change), where chogui and chogui-three ship together on a publish-together version policy.