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

@gem-org/gemffects

v1.1.0

Published

Gemffects — librería React de efectos visuales

Readme

📑 Contents

📦 Installation

npm install @gem-org/gemffects

The consuming application must use react and react-dom ^19.

@gem-org/gem-system is an optional peer. Gemffects reads --gem-* tokens from the host when they exist, and falls back to neutral values otherwise. It does not reimplement Button, inputs, Modal, Shine, Transition, Skeleton, Spinner, or Indicator.

🚀 Basic usage

Import the complete stylesheet once in your application entry point, then wrap UI with an effect:

import "@gem-org/gemffects/styles.css";
import { Glow, Ripple } from "@gem-org/gemffects";

export function SaveAction() {
  return (
    <Glow>
      <Ripple>
        <button type="button">Save</button>
      </Ripple>
    </Glow>
  );
}

The main package import is convenient for prototypes or applications that use most of the library.

🧩 As child

By default each effect renders a wrapping div. Pass asChild to merge classes, CSS variables, and listeners onto the single child — useful in Flex/Grid or on a real button:

import "@gem-org/gemffects/ripple.css";
import { Ripple } from "@gem-org/gemffects/ripple";

export function SaveRipple() {
  return (
    <Ripple asChild>
      <button type="button">Save</button>
    </Ripple>
  );
}

asChild requires exactly one React element child. Overlay layers (ripples, particles, halos) are injected inside that element.

🪝 Headless hooks

Pointer effects also ship as hooks so you can attach motion to an existing node without the wrapper. Tilt3D, Magnetic, and Spotlight call the same hook internally.

import "@gem-org/gemffects/tokens.css";
import "@gem-org/gemffects/tilt-3d.css";
import { useTilt3D } from "@gem-org/gemffects/tilt-3d";

export function TiltButton() {
  const { ref, style, pointerProps, isTracking, motionClassName } = useTilt3D({
    intensity: "md",
  });

  return (
    <button
      type="button"
      ref={ref}
      className={[
        "gemfx-tilt3d",
        isTracking && "gemfx-tilt3d--tracking",
        motionClassName,
      ].filter(Boolean).join(" ")}
      style={style}
      {...pointerProps}
    >
      <span className="gemfx-tilt3d__surface">Save</span>
    </button>
  );
}

useMagnetic returns { ref, style, transform, pose }. useSpotlight returns overlay coords on pose (x / y percentages) and the same --gemfx-spotlight-* variables on style; you render the beam layer. Add the returned motionClassName to a headless host when using ignoreReducedMotion.

⚡ Optimized imports

To load only what your application uses, import the motion tokens, the effect stylesheet, and the effect subpath:

import "@gem-org/gemffects/tokens.css";
import "@gem-org/gemffects/ripple.css";
import { Ripple } from "@gem-org/gemffects/ripple";

export function SaveRipple() {
  return (
    <Ripple>
      <button type="button">Save</button>
    </Ripple>
  );
}

Import tokens.css only once. Some effects also require stylesheets from shared modules:

  • ParticleBurst, ParticleRain, and Rip use particles.css.
  • CSS aliases: @gem-org/gemffects/holo-foil.css → holofoil.css, @gem-org/gemffects/tilt-3d.css → tilt3d.css.

If you prefer not to manage these style dependencies, use styles.css. JavaScript helpers are available from @gem-org/gemffects/utils, motion tokens from @gem-org/gemffects/tokens, and the particle runtime from @gem-org/gemffects/particles.

🧩 Effect catalog

Gemffects includes 27 effects, organized by purpose. Public classes use the .gemfx-* prefix (BEM). Effect parameters use --gemfx-* custom properties.

🌟 Aura, light, and neon

  • Glow (/glow) — rear neon glow with a breathing pulse.
  • Spotlight (/spotlight) — circular light that follows the pointer.
  • BorderBeam (/border-beam) — neon beam that travels the container edge.
  • Flash (/flash) — brief white or gold burst over the child.

🌀 3D and motion

  • Tilt3D (/tilt-3d) — interactive 3D tilt from the pointer.
  • Float (/float) — continuous vertical levitation.
  • Magnetic (/magnetic) — subtle attraction toward the cursor.
  • Zoom (/zoom) — scale the child (in, out, pulse, or lens at the pointer).
  • PulseScale (/pulse-scale) — attention beat for CTAs.
  • Vortex (/vortex) — spatial swirl on hover (cards).

🎨 Style, filters, and retro

  • HoloFoil (/holo-foil) — multicolor holographic sheen.
  • Flicker (/flicker) — retro neon flicker.
  • Glitch (/glitch) — RGB split distortion.
  • Glassmorphism (/glassmorphism) — frosted glass with backdrop blur.
  • BlurUnveil (/blur-unveil) — blur-to-sharp reveal (typically images).
  • Marquee (/marquee) — infinite looping marquee.
  • ScrambleText (/scramble-text) — matrix-style decode for titles.
  • Noise (/noise) — photographic grain overlay.

🎨 Gradients and meshes

  • GradientText (/gradient-text) — text filled with a sliding, pulsing, or static color gradient (from / via / to).
  • GradientMesh (/gradient-mesh) — liquid moving mesh of soft color blobs behind the child.
  • GradientBorder (/gradient-border) — dynamic gradient stroke around the container edge.
  • GradientGlossy (/gradient-glossy) — zenith glossy lighting: 3-stop gradient from any base color plus inset sheen; direction is to-bottom / to-top / to-right / to-left.

🎆 Particles and interactions

  • ParticleBurst (/particle-burst) — confetti or sparks on click. Needs particles.css.
  • ParticleRain (/particle-rain) — falling confetti, stars, or lights. Needs particles.css.
  • Ripple (/ripple) — expanding wave from the pointer.
  • Rip (/rip) — scratch or tear trail with optional debris. Needs particles.css.
  • RipZone (/rip-zone) — scratch-off cover that reveals the child (lottery-card scrape).
  • Meteors (/meteors) — shooting-star field in a container.
  • Unlock (/unlock) — door-style cover that opens from the center (horizontal / vertical) or slides away (left / right / up / down); variant is unlock or lock. Door face via coverSrc (image URL) or cover (node or (slot) => node factory for splits), else solid color.

Shared wrapper API

Effects wrap children. Typical props: asChild, trigger, isActive, isPaused, duration, delay, intensity, className, classNames. Pointer effects also export headless hooks (useTilt3D, useMagnetic, useSpotlight). Lifecycle callbacks follow onGlow / outGlow (and the matching name per effect). Overlays are aria-hidden. Pointer events on the child stay enabled unless the effect itself is the control (Rip, RipZone).

Every effect respects prefers-reduced-motion: reduce by default. Set ignoreReducedMotion only when motion is essential to the intended experience; the same option is available in the headless hooks.

Pointer-tracking effects (Tilt3D, Magnetic, Spotlight, HoloFoil, and Zoom) accept disabledOnTouch, defaulting to true: touch-origin tracking is skipped while mouse and pen keep working. Set it to false only when following a finger is intentional.

Gesture and tap effects (RipZone, Rip, Ripple, Flash, ParticleBurst, and ParticleRain) expose the same prop but default it to false, so scratch, drag, tap, press, and hold remain usable on touch. Set it to true to ignore touch-origin gestures without disabling mouse or pen input. trigger="always" is unaffected. Gyroscope input is outside the v1 scope.

🎆 Particles

The shared particle field lives at @gem-org/gemffects/particles:

import "@gem-org/gemffects/tokens.css";
import "@gem-org/gemffects/particles.css";
import "@gem-org/gemffects/particle-burst.css";
import { ParticleBurst } from "@gem-org/gemffects/particle-burst";

ParticleLayer, useParticleField, and spawn helpers are public if you need a custom burst. Kinds include spark, star, confetti, and light.

🎨 Motion tokens

Duration, easing, and intensity are Gemffects-owned. They ship as TypeScript maps and as --gemfx-* CSS variables generated from those maps. Palette, type, space, and radius stay on the host (--gem-*).

import {
  duration,
  easing,
  intensity,
  mixIntensity,
} from "@gem-org/gemffects/tokens";

Load the CSS variables once:

import "@gem-org/gemffects/tokens.css";

Helpers such as cx and useEffectPhase are available from @gem-org/gemffects/utils.

🛠️ Scripts

  • npm run dev — starts Storybook at http://localhost:6006.
  • npm run build — builds the library, subpaths, and CSS files into dist/.
  • npm run build-storybook — builds the static documentation.
  • npm run bundle — measures dist module and stylesheet sizes.
  • npm run typecheck — checks TypeScript types.
  • npm run lint — runs ESLint.

🧑‍💻 Development

  • Effects live in src/effects/<Name>/.
  • Motion tokens live in src/tokens/ (duration, easing, intensity).
  • Generated CSS variables live in src/styles/tokens.scss. Storybook loads src/styles/effects.scss.
  • Particle runtime lives in src/particles/.
  • SCSS is colocated with each effect. Published TSX does not import SCSS; consumers load ./name.css.
  • Public classes use the .gemfx-* prefix and BEM naming.
  • TypeScript is strict and any is not allowed.
  • Storybook is the development and documentation environment.

📄 License

MIT