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

nui-rainbow

v0.1.0

Published

Rainbow hue cycle for any element. Web component, CSS class, or applyRainbow().

Readme

Rainbow hue cycle on --rainbow-hue. Use the web component, a CSS class, or applyRainbow().

Install

npm install nui-rainbow

Web component

<script type="module">
  import 'nui-rainbow';
</script>

<nui-rainbow duration="12s">
  <h1>Hue lives on --rainbow-hue</h1>
</nui-rainbow>
h1 {
  color: hsl(var(--rainbow-hue) 55% 52%);
}

Or use a ready-made token:

h1 {
  color: var(--nui-rainbow-color);
  background: var(--nui-rainbow-color-soft);
  border-color: var(--nui-rainbow-complement);
}

Vue:

<nui-rainbow :duration="speed" :paused="paused" initial-hue="210deg">
  <slot />
</nui-rainbow>

Props / attributes

| Prop | Attribute | Default | Notes | |---|---|---|---| | duration | duration | 30s | Number = seconds (1212s). Also 800ms. | | initialHue | initial-hue | 132deg | Cycle origin. Alias: from. | | from | from | 132deg | Same as initialHue. Wins when both are set. | | to | to | origin + 360deg | Sets span to to - from. | | hueSpan | hue-span | 360deg | How far the cycle travels. Ignored when to is set. | | offset | offset | 0deg | Extra hue shift (stagger children). | | easing | easing | linear | Any CSS easing. | | iterations | iterations | infinite | Number or infinite. | | delay | delay | 0s | Number = seconds. | | paused | paused | false | Boolean attribute. | | direction | direction | normal | normal / reverse / alternate / alternate-reverse. | | fillMode | fill-mode | none | none / forwards / backwards / both. | | cycle | cycle | branded | branded (curved path) or linear (even 360°). | | reducedMotion | reduced-motion | reduce | ignore keeps motion when the user prefers reduced motion. | | saturation | saturation | 55% | Used by color tokens. Number = percent. | | lightness | lightness | 52% | Used by color tokens. Number = percent. | | alpha | alpha | 1 | Used by color tokens. |

<nui-rainbow> emits rainbowcycle on each animation iteration (detail.animationName).

Class or helper

import { applyRainbow } from 'nui-rainbow';

const stop = applyRainbow(document.querySelector('.surface'), {
  duration: 45,
  paused: false,
  cycle: 'linear',
  offset: 24,
});

el.addEventListener('rainbowcycle', () => { /* next lap */ });

stop();
<div class="nui-rainbow" style="--nui-rainbow-duration: 12s">
  …
</div>
@import 'nui-rainbow/styles.css';

.surface {
  color: hsl(var(--rainbow-hue) 55% 52%);
}

.nuc-rainbow is an alias of .nui-rainbow.

CSS-only usage does not emit rainbowcycle. Call bindRainbowCycle(el) if you need the event without applyRainbow().

Recipes

Add a recipe class on the cycling element or a descendant (--rainbow-hue inherits):

| Class | Effect | |---|---| | .nui-rainbow-text | Rainbow gradient clipped to text. | | .nui-rainbow-border | Border tinted with --nui-rainbow-color. | | .nui-rainbow-underline | Underline tinted with --nui-rainbow-color. |

.nuc-rainbow-text, .nuc-rainbow-border, and .nuc-rainbow-underline are aliases.

<nui-rainbow class="nui-rainbow-text">Hello</nui-rainbow>

--rainbow-hue inherits, so a child can add its own shift:

.letter {
  color: hsl(
    calc(var(--rainbow-hue) + var(--nui-rainbow-offset, 0deg))
      var(--nui-rainbow-saturation) var(--nui-rainbow-lightness)
  );
}
<div class="nui-rainbow">
  <span style="--nui-rainbow-offset: 0deg">A</span>
  <span style="--nui-rainbow-offset: 24deg">B</span>
  <span style="--nui-rainbow-offset: 48deg">C</span>
</div>

Or put .nui-rainbow on each letter with a different --nui-rainbow-offset so tokens like --nui-rainbow-color pick up the shift.

Compose with another animation

The cycle lives on --nui-rainbow-animation. Keep another animation without overwriting it:

.surface {
  --nui-rainbow-extra-animation: fade-in 0.4s ease;
}

Or list it yourself:

.surface {
  animation: fade-in 0.4s ease, var(--nui-rainbow-animation);
}

CSS variables

Set these on the same element that has the class / component:

| Variable | Role | |---|---| | --rainbow-hue | Public hue token for hsl() / oklch(). | | --nui-rainbow-color | hsl(hue saturation lightness / alpha). | | --nui-rainbow-color-soft | Lighter, less saturated sibling. | | --nui-rainbow-color-muted | Duller sibling. | | --nui-rainbow-complement | Opposite hue, same S/L/alpha. | | --nui-rainbow-complement-hue | --rainbow-hue + 180deg. | | --nui-rainbow-oklch | Same cycle in oklch(). | | --nui-rainbow-duration | Cycle length. | | --nui-rainbow-initial-hue | Cycle origin. | | --nui-rainbow-from | Hue at progress 0 (defaults to initial hue). | | --nui-rainbow-to | Computed from + span. | | --nui-rainbow-span | Travel distance (default 360deg). | | --nui-rainbow-offset | Extra hue shift. | | --nui-rainbow-easing | Timing function. | | --nui-rainbow-iterations | Repeat count. | | --nui-rainbow-delay | Start delay. | | --nui-rainbow-direction | Animation direction. | | --nui-rainbow-fill-mode | animation-fill-mode. | | --nui-rainbow-saturation | For color tokens. | | --nui-rainbow-lightness | For color tokens. | | --nui-rainbow-alpha | For color tokens. | | --nui-rainbow-animation | Full cycle shorthand. | | --nui-rainbow-extra-animation | Optional extra animation to compose. |

prefers-reduced-motion: reduce stops the animation unless reduced-motion="ignore".

Styles

applyRainbow() / <nui-rainbow> adopt a constructable stylesheet when the document supports it, and fall back to a <style id="nui-rainbow-styles"> tag. For a shadow root:

import { getRainbowStyleSheet } from 'nui-rainbow';

shadow.adoptedStyleSheets = [...shadow.adoptedStyleSheets, getRainbowStyleSheet()];