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

@staticcanvas/lume

v0.37.1

Published

Zero-dependency contextual tooltip engine with smart collision detection and DOM mutation awareness.

Readme

@staticcanvas/lume

npm-version jsr-version codecov license

Lume is a lightweight, zero-dependency JavaScript tooltip engine providing mutation-aware DOM lifecycle management, collision detection, and hardware-accelerated positioning.


Highlights

  • Zero Dependencies — Pure vanilla ESM/CJS build with a small production bundle checked against a 5 KB gzip budget.
  • Single-Node DOM Recycling — Reuses a single .lume-tooltip element to eliminate DOM bloat and thrashing.
  • Hardware-Accelerated Positioning — 60fps positioning powered by translate3d(x, y, 0).
  • Priority-Aware Collision Detection — Evaluates the complete tooltip rectangle, follows ordered fallback sides, and clamps only as a final safeguard near viewport edges.
  • Mutation-Aware Lifecycle — Automatically discovers newly inserted DOM elements and purges orphan tooltips without re-binding.
  • Formatting Tokens — Supports safe text formatting tokens, lists, line breaks, and composite pastel styles using the {/lme} terminator.
  • Editor Syntax Support — Includes VS Code, Neovim, and Zed LIRL syntax definitions in the repository's editors/ directory.
  • Trusted HTML Mode — Renders application-owned data-lume-content only with allowHTML: true; untrusted content must remain in text mode.
  • Reference Presentation Tiers — Minimal, simple, and advanced layouts support structured LIRL content.
  • Visual Decorations — Includes a CSS-only outlined info icon and custom-color pastel status dots.
  • Viewport-Safe Content — Constrains width and keeps unusually tall content inside the tooltip content region.
  • Configurable Interaction — Supports hover/focus or click/tap activation, motion presets, intensity, delays, alignment, boundaries, custom containers, and per-trigger overrides.
  • Optional Diagnostics — Metrics and debug modules can be loaded separately when needed.
  • Accessible — First-class keyboard focus/blur support and WAI-ARIA roles (role="tooltip", aria-hidden).

Installation

npm install @staticcanvas/lume
# Or using pnpm / yarn / bun
pnpm add @staticcanvas/lume
yarn add @staticcanvas/lume
bun add @staticcanvas/lume

Quick Start

1. Import JavaScript and CSS

import { Lume } from '@staticcanvas/lume';
import '@staticcanvas/lume/css';

// Automatically discovers and binds [data-lume] and [data-lume-content] elements
const lume = new Lume();

2. Add Markup

<!-- Basic Tooltip -->
<button data-lume="Save your project changes">Save</button>

<!-- Tooltip with Title and Custom Direction -->
<button
  data-lume="Export your dataset as CSV, JSON, or XML."
  data-lume-title="Export Options"
  data-lume-direction="bottom"
>
  Export
</button>

<!-- Inline Help Badge -->
<span class="lume-inline" data-lume="Contextual information preview"> More Info </span>

Trusted HTML content

Use HTML mode only for application-owned markup. It is not an HTML sanitizer.

const lume = new Lume({ allowHTML: true });
<button data-lume-content="<strong>Status:</strong> <span>Online</span>">Account status</button>

HTML content can be styled with .lume-tooltip and custom classes. Omit data-lume-title when the HTML body is the complete tooltip.


Declarative Data Attributes

| Attribute | Type | Default | Description | | :----------------------- | :--------------- | :------------------------ | :-------------------------------------------------------------------------- | | data-lume | string | "" | Plain-text tooltip content with optional Lume formatting tokens. | | data-lume-title | string | "" | Optional header title rendered in .lume-header. | | data-lume-direction | string | "top" | Preferred direction: "auto", "top", "bottom", "left", or "right". | | data-lume-priority | string | "top,bottom,right,left" | Comma-separated fallback order for automatic and smart placement. | | data-lume-offset | number | 14 | Distance in pixels between target element and tooltip. | | data-lume-content | string | "" | Explicit content source; rendered as HTML only with allowHTML. | | data-lume-icon | string | "" | Application-owned SVG URL or info for the outlined info icon. | | data-lume-dot | CSS color | "" | Optional single-color status dot with pastel presentation. | | data-lume-dot-position | direction | left | Position of the status dot. | | data-lume-class | string | "" | Custom CSS class modifier for per-element styling. | | data-lume-action | hover \| click | hover | Per-element interaction model. | | data-lume-motion | preset | fade | Per-element motion preset. | | data-lume-intensity | number | 1 | Per-element motion intensity from 0 through 3. | | data-lume-smart | boolean | true | Per-element collision detection override. |


Programmatic API

import { Lume } from '@staticcanvas/lume';

const lume = new Lume({
  offset: 16, // Default pixel offset
  smart: true, // Enable collision flip
  className: 'theme', // Global custom class
  motion: 'lift',
  motionIntensity: 1,
  showDelay: 0,
  hideDelay: 0,
  padding: 10,
});

const button = document.querySelector('#action-btn');

// Show tooltip on a specific element
lume.show(button);

// Force position recalculation (e.g. after layout changes)
lume.reposition();

// Hide active tooltip
lume.hide();

// Destroy instance and remove DOM nodes
lume.destroy();

Framework Integration

React

import { useEffect } from 'react';
import { Lume } from '@staticcanvas/lume';
import '@staticcanvas/lume/css';

export function MyComponent() {
  useEffect(() => {
    const lume = new Lume();
    return () => lume.destroy();
  }, []);

  return (
    <button data-lume="Saved to cloud" data-lume-title="Status">
      Save
    </button>
  );
}

Vue 3

<script setup>
import { onMounted, onUnmounted } from 'vue';
import { Lume } from '@staticcanvas/lume';
import '@staticcanvas/lume/css';

let lume;

onMounted(() => {
  lume = new Lume();
});

onUnmounted(() => {
  lume?.destroy();
});
</script>

<template>
  <button data-lume="Vue Tooltip" data-lume-direction="bottom">Hover me</button>
</template>

Styling & CSS Variables

Easily theme tooltips using CSS custom properties:

:root {
  --lume-bg: #0f172a;
  --lume-text: #f8fafc;
  --lume-accent: rgba(255, 255, 255, 0.15);
  --lume-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3);
  --lume-radius: 8px;
  --lume-font-size: 13px;
  --lume-max-width: 280px;
}

Optional diagnostics

Diagnostics are separate modules so the core runtime remains focused:

import { createLumeMetrics } from '@staticcanvas/lume/metrics';
import { createLumeDebug } from '@staticcanvas/lume/debug';

const metrics = createLumeMetrics(lume);
const debug = createLumeDebug(lume);
console.table(metrics.snapshot());
// metrics.dispose();
// debug.dispose();

Links


License

Distributed under the MIT License. See LICENSE for more information.