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

gemrenderer

v0.3.0

Published

A generic gemstone renderer: colour + cut family + real optics, ray-traced light paths in one shared WebGL context

Readme

gemrenderer

Gemstones, cut the way they're meant to be. Ray-traced in the browser, with no frontend framework required.

Support

gemrenderer is free and MIT licensed. If you find it useful, you can support its development:

Donate with PayPal

The gemrenderer demo: gemstones in a range of cuts rendered in the browser

gemrenderer renders gemstones by describing them in parts: a body colour, a cut, and a few optical constants. From there it builds the geometry and traces light through each facet. Fresnel reflection, refraction, total internal reflection and exit all come into play, with red, green and blue bending slightly differently to produce real chromatic fire. As light travels inside the stone, Beer–Lambert absorption deepens the colour based on the body colour, refractive index and dispersion.

The library doesn't hardcode any specific gemstone names. Instead, it ships a set of ready-made stones (benitoite, red beryl, musgravite, painite, alexandrite, paraíba, sapphire, emerald, ruby and diamond) as presets in gemrenderer/presets. You can use them as-is, or define your own from scratch.

  • Works with or without a framework. There's a vanilla DOM class, plus a small pure-function core and pointer gesture. You can also use it in Vue, React, Svelte or plain HTML/JS.
  • Optionally glinting. configure({ glint }) adds a small bloom pass so the facets that catch the studio's hot spots flare softly instead of clipping to hard white. Off by default — no post pass, no cost.
  • One WebGL context for the whole page. Stones are baked once per (spec, clarity) and cached. Static images and live spinners share the same meshes, so nothing is wasted.
  • Falls back gracefully without WebGL. If the browser can't create a WebGL context, it keeps a placeholder and your layout stays intact.
  • No assets, no build step. Everything runs from plain ESM source with a small procedural HDR studio.
  • MIT licensed.

Demo

rubjo.github.io/gemrenderer — Every preset on display; drag any of them to spin it. Feature a stone, then make it yours: changing its colour or cut (or hitting Randomize) turns the featured stone into a Custom one — the optics knobs on the panel (fire, light paths, glint) belong to the ray-traced path and grey out when the renderer is set to rasterised.

Install

npm install gemrenderer three

three is a peer dependency (>=0.163). Use the version your app already ships. gemrenderer loads three.js lazily, only when it actually needs to render.

import { GemView } from 'gemrenderer'

// Define your own stone: a square-cut deep red brilliant
new GemView('#mount', {
  color: 0xa6001a,
  cut: { family: 'brilliant', poly: 4 },
  ior: 1.77,
  fire: 0.41,
  clarity: 8,
})

// Or use one of the built-in presets
import { gemSpec } from 'gemrenderer/presets'
new GemView('#mount', { ...gemSpec('ruby'), clarity: 8 })

That's it for most use cases. A placeholder appears first, then the baked stone replaces it. Once you drag it, it becomes a live canvas that spins freely in both directions and eases back to its resting position when you let go.

Per-stone looks come from the spec; page-wide knobs — brightness everywhere, plus dispersion, light paths and glint on the ray-traced path — are set once with configure() and re-bake every mounted stone lazily. An individual spec can also pin its own fire, bright, bounces or glint, so one stone gets different optics without touching the others. A design note on the glint pass lives in docs/glint.md.