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

@fluentez/ui

v1.0.2

Published

Zero-dependency 100% matching UI skeleton generator for Vanilla JS and React

Readme

@fluentez/ui

Zero-dependency 100% matching UI skeleton screen generator for Vanilla JavaScript and React applications.

Automatically inspects existing DOM elements—measuring layout geometries, spacing, text heights, images, inputs, and border radiuses—to generate pixel-perfect skeleton loading placeholders with customizable animations.

Key Features

  • 100% Geometry Match: Reads computed styles and bounding rects directly from existing UI elements.
  • Zero External Dependencies: Pure native Web APIs (getBoundingClientRect, getComputedStyle, CSS keyframe animations).
  • Vanilla JS & React: Built-in support for standard DOM manipulation and React hooks/components.
  • Custom Animations: Smooth built-in shimmer, pulse, wave, or none animation modes.
  • Flexible Exclusions: Skip or preserve specific elements using selectors or predicate functions (exclude, keep, data-skeleton-ignore, data-skeleton-keep).
  • Dark/Light Theme Support: Automatic color palette detection based on system preferences or custom color themes.

Quick Navigation Index

| Feature / API | Subpath Import Path | Quick Direct Links | | :--- | :--- | :--- | | createSkeleton (Vanilla Core) | @fluentez/ui | Overview | Parameters | Returns | Vanilla Examples | | SkeletonContainer (React Component) | @fluentez/ui/react | React Component Usage | Data Attributes | | useSkeleton (React Hook) | @fluentez/ui/react | React Hook Usage | API Reference |


Installation

bun add @fluentez/ui
# or
npm install @fluentez/ui
# or
pnpm add @fluentez/ui

Quick Start & Examples

Vanilla JavaScript

import { createSkeleton } from '@fluentez/ui';

const targetCard = document.querySelector('#user-profile-card');

// 1. Create skeleton loader overlay matching targetCard UI
const skeleton = createSkeleton(targetCard, {
  animation: 'shimmer',
  theme: 'auto',
  borderRadius: 'auto',
  fadeDuration: 250,
});

// 2. Hide skeleton and restore original UI once data is loaded
fetchUserData().then((user) => {
  renderUserProfile(user);
  skeleton.restore();
});

Advanced Customization (Custom Theme Palette & Exclusions)

import { createSkeleton } from '@fluentez/ui';

const skeleton = createSkeleton('#product-card', {
  animation: 'wave',
  theme: {
    background: '#1e1e2e',
    skeleton: '#313244',
    highlight: 'rgba(255, 255, 255, 0.12)',
  },
  borderRadius: 12,
  // Skip action buttons
  exclude: '.action-btn, button',
  // Keep brand logo visible untouched
  keep: '.brand-logo',
});

React Integration

Option 1: <SkeletonContainer> Component

import React from 'react';
import { SkeletonContainer } from '@fluentez/ui/react';

export function ProfileCard({ user, loading }: { user?: User; loading: boolean }) {
  return (
    <SkeletonContainer loading={loading} options={{ animation: 'shimmer', theme: 'auto' }}>
      <div className="card">
        <img src={user?.avatar} alt={user?.name} className="avatar" />
        <h2>{user?.name}</h2>
        <p>{user?.bio}</p>
      </div>
    </SkeletonContainer>
  );
}

Option 2: useSkeleton Hook

import React from 'react';
import { useSkeleton } from '@fluentez/ui/react';

export function UserFeed({ isLoading }: { isLoading: boolean }) {
  const containerRef = useSkeleton<HTMLDivElement>(isLoading, {
    animation: 'pulse',
  });

  return (
    <div ref={containerRef} className="feed-container">
      <article className="post-item">
        <h3>Post Title Placeholder</h3>
        <p>Post body description placeholder text.</p>
      </article>
    </div>
  );
}

API Reference

createSkeleton(target, options) / skeletonize(target, options)

Generates a skeleton overlay on the target element.

Parameters

  • target: HTMLElement | string — Target element or selector query string.
  • options: SkeletonOptions — Optional configuration object.

Options (SkeletonOptions)

| Option | Type | Default | Allowed Values & Description | | :--- | :--- | :--- | :--- | | animation | 'shimmer' \| 'pulse' \| 'wave' \| 'none' | 'shimmer' | Animation effect style for skeleton blocks. | | theme | 'auto' \| 'light' \| 'dark' \| { skeleton?, highlight?, background? } | 'auto' | Color theme or custom object: skeleton (or background) sets base block color, highlight sets shimmer light streak color. | | borderRadius | 'auto' \| number \| string | 'auto' | Border radius resolution mode ('auto', number pixels, or CSS string). | | exclude | string \| ((el: HTMLElement) => boolean) | undefined | Selector or predicate matching elements to skip completely. | | keep | string \| ((el: HTMLElement) => boolean) | undefined | Selector or predicate matching elements to remain visible as-is. | | fadeDuration | number | 250 | Fade-out duration in milliseconds when restoring UI. | | className | string | '' | Custom CSS class string for overlay container. | | ignoreHidden | boolean | true | When true, ignores display: none or visibility: hidden elements. |

Return Value (SkeletonController)

| Method / Property | Type | Description | | :--- | :--- | :--- | | restore() | () => void | Removes skeleton overlay and smoothly restores original UI. | | skeletonElement | HTMLElement | Reference to generated overlay container DOM element. | | targetElement | HTMLElement | Reference to target container DOM element. | | isDestroyed | boolean | Read-only boolean property indicating whether skeleton has already been restored. |


HTML Data Attributes

Mark elements directly in HTML to control skeleton generation behavior without writing custom options:

  • data-skeleton-ignore: Skips skeleton creation for this element and its children.
  • data-skeleton-keep: Keeps this element visible and untouched inside the skeleton view (useful for brand logos or static icons).
<div id="card">
  <h2>User Title</h2>
  <!-- Icon will stay visible as is during loading -->
  <svg data-skeleton-keep class="icon">...</svg>
  <!-- Action button won't be replaced by skeleton -->
  <button data-skeleton-ignore>Action</button>
</div>

License

MIT © Fluentez Ecosystem