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

skeleton-ui-loader

v0.1.12

Published

Zero-config React skeleton loader generated from real DOM structure.

Readme

skeleton-ui-loader

Zero-config React skeleton loaders generated automatically from your real component DOM.

Stop writing skeleton markup. Wrap your component → instant, perfect skeleton. No duplication. No maintenance.

npm downloads license


The Problem

Every React app needs skeleton loaders, but building and maintaining them takes time:

// Manual skeleton markup for each component
const UserCardSkeleton = () => (
  <div className="animate-pulse">
    <div className="h-8 w-8 bg-gray-200 rounded-full"></div>
    <div className="h-4 w-20 bg-gray-200 mt-2"></div>
    <div className="h-3 w-32 bg-gray-200 mt-1"></div>
  </div>
);
  • Duplicate markup everywhere
  • Fragile — breaks when you refactor
  • Time-wasting — hours per project
  • Inconsistent — different devs build skeletons differently

The Solution

Just wrap ANY component or HTML element:

import { SkeletonAuto } from "skeleton-ui-loader";
import "skeleton-ui-loader/styles.css";

// Works with React components
function UserCard({ loading }) {
  return (
    <SkeletonAuto loading={loading}>
      <YourComponent />
    </SkeletonAuto>
  );
}

// Works with any HTML structure
function Article({ loading }) {
  return (
    <SkeletonAuto loading={loading}>
      <div className="article">
        <h1>Title</h1>
        <img src="..." alt="cover" />
        <p>Content paragraph...</p>
        <button>Read More</button>
      </div>
    </SkeletonAuto>
  );
}

// Works with simple divs
<SkeletonAuto loading={isLoading}>
  <div>
    <div className="avatar"></div>
    <div className="name">John Doe</div>
  </div>
</SkeletonAuto>

You get matching skeletons without maintaining duplicate markup. Works with any div or HTML structure.


Works With ANYTHING

// React components
<SkeletonAuto loading={loading}><MyComponent /></SkeletonAuto>

// HTML divs
<SkeletonAuto loading={loading}><div>...</div></SkeletonAuto>

// Nested structures
<SkeletonAuto loading={loading}>
  <article>
    <h1>Title</h1>
    <img />
    <p>Content</p>
  </article>
</SkeletonAuto>

// Complex layouts
<SkeletonAuto loading={loading}>
  <section className="card">
    <header>
      <img className="avatar" />
      <h2>Name</h2>
    </header>
    <body>
      <p>Description</p>
    </body>
    <footer>
      <button>Action</button>
    </footer>
  </section>
</SkeletonAuto>

One wrapper around your UI, and skeletons are generated from the real layout.


Why skeleton-ui-loader

  • Works with any HTML — React components, divs, and complex layouts
  • Auto-generated — scans real DOM and builds matching placeholders
  • Themeable — colors, radius, and animations are customizable
  • Performant — snapshot mode caches layouts for repeat renders
  • SSR-safe — works with Next.js, Remix, and other React frameworks
  • TypeScript friendly — includes type safety and IntelliSense support

Install

npm i skeleton-ui-loader

Requires:

  • React ≥ 17
  • react-dom ≥ 17

30-Second Setup

Wrap any component or HTML element. Skeleton generates automatically.

import { SkeletonAuto } from "skeleton-ui-loader";
import "skeleton-ui-loader/styles.css";

export function MyComponent() {
  const [loading, setLoading] = useState(true);

  return (
    <SkeletonAuto loading={loading} animation="shimmer">
      {/* Works with React components, divs, any HTML */}
      <YourComponent />
    </SkeletonAuto>
  );
}

That's all. Skeleton auto-generates from ANY div or HTML element inside.


API

<SkeletonAuto />

Wrap any component. Skeleton generates automatically.

<SkeletonAuto
  loading={isLoading}
  baseColor="#2b2f36"        // Skeleton background
  shimmerColor="#3a404a"     // Animation highlight
  borderRadius={12}          // Corner radius
  animation="shimmer"        // shimmer | pulse | wave | none
  snapshot="user-card-v1"    // Optional: cache layout
>
  <YourComponent />
</SkeletonAuto>

| Prop | Type | Default | What it does | |------|------|---------|---| | loading | boolean | required | Show skeleton when true | | children | ReactNode | required | Component to scan | | baseColor | string | #e0e0e0 | Skeleton color | | shimmerColor | string | #f0f0f0 | Animation highlight | | animation | "shimmer" \| "pulse" \| "wave" \| "none" | "shimmer" | Animation style | | borderRadius | number | 4 | Corner radius | | snapshot | string | — | Cache key (optional) | | maxDepth | number | 12 | DOM traversal depth | | minWidth | number | 2 | Skip elements narrower than this | | minHeight | number | 2 | Skip elements shorter than this |


useSkeletonAuto() — For Custom Control

import { useSkeletonAuto } from "skeleton-ui-loader";

function ManualMode() {
  const { skeletonRef, SkeletonOverlay, snap } = useSkeletonAuto({
    animation: "wave",
    baseColor: "#1f2a39",
    shimmerColor: "#32445b",
    borderRadius: 12
  });

  return (
    <div style={{ position: "relative" }}>
      <div ref={skeletonRef} style={loading ? { opacity: 0.001 } : {}}>
        <YourContent />
      </div>
      {loading && <SkeletonOverlay />}
      <button onClick={snap}>Refresh layout</button>
    </div>
  );
}

How It Works

What happens under the hood:

  1. Scans your real component's DOM
  2. Classifies elements (headings, images, text, buttons)
  3. Generates a perfect skeleton matching that structure
  4. Animates with shimmer, pulse, wave, or static
  5. Caches layouts (optional) for performance

Classification:

| Element Type | Skeleton | |---|---| | <h1> ... <h6> | Heading bar | | <img>, <picture> | Image placeholder | | <button>, <input> | Control shape | | Text nodes | Content bars | | Containers | Structural blocks |


Advanced Features

Snapshot Mode (Caching)

Use snapshot to cache layouts for components shown repeatedly:

<SkeletonAuto loading={loading} snapshot="product-card-v1">
  <ProductCard />
</SkeletonAuto>

When to use:

  • Component layout is stable
  • Shows frequently (list of 100 items)

When to skip:

  • Layout changes often
  • Dynamic content structure

Fine-Tune with Data Attributes

Mark key elements:

<article data-skeleton-id="user-card-root">
  <div data-skeleton-container="true">
    {/* Mark container surfaces for better skeletons */}
  </div>
</article>

| Attribute | Purpose | |---|---| | data-skeleton-id | Stable identity for snapshot matching | | data-skeleton-container | Force container to be structural block |


Customize Depth & Granularity

<SkeletonAuto
  maxDepth={8}      // Stop at 8 levels deep
  minWidth={10}     // Skip elements <10px wide
  minHeight={3}     // Skip elements <3px tall
>
  <Component />
</SkeletonAuto>

Fix noisy skeletons: Increase minWidth and minHeight.


Animation Styles

4 built-in animations:

| Animation | Effect | |---|---| | shimmer | Light wave across skeleton (default) | | pulse | Smooth fade in/out | | wave | Directional highlight sweep | | none | Static (no animation) |

<SkeletonAuto animation="pulse">
  <Component />
</SkeletonAuto>

Common Patterns

Loading a List

<ScrollRevealList>
  {items.map((item) => (
    <SkeletonAuto key={item.id} loading={loading}>
      <Card item={item} />
    </SkeletonAuto>
  ))}
</ScrollRevealList>

Dark Mode Support

<SkeletonAuto
  loading={loading}
  baseColor={isDark ? "#1a1a1a" : "#e0e0e0"}
  shimmerColor={isDark ? "#333" : "#f0f0f0"}
>
  <Component />
</SkeletonAuto>

Custom Styling

<SkeletonAuto
  loading={loading}
  className="my-skeleton"
  style={{ borderRadius: "16px" }}
>
  <Component />
</SkeletonAuto>

Troubleshooting

"Skeleton looks wrong / too noisy"

Solution: Increase minWidth and minHeight

<SkeletonAuto minWidth={12} minHeight={8}>
  <Component />
</SkeletonAuto>

"Snapshot looks stale"

Solution: Change snapshot key when structure changes

// Old: snapshot="card-v1"
// New: snapshot="card-v2"  ← Different key = fresh cache

Or clear snapshot:

import { clearSnapshot } from "skeleton-ui-loader";

clearSnapshot("card-v1");  // Clear one
clearSnapshot();           // Clear all

"Skeleton doesn't match special sections"

Solution: Use data-skeleton-id and data-skeleton-container

<section data-skeleton-id="hero-section" data-skeleton-container="true">
  <Component />
</section>

Performance Tips

  • Use snapshot for stable layouts shown frequently
  • Set maxDepth lower on very deep component trees
  • Raise minWidth/minHeight to skip micro-elements
  • Use data-skeleton-id on key containers for reliable matching

Bundle size: Only 3KB. Zero runtime dependencies.


Utility Exports

Advanced use cases:

import {
  clearSnapshot,        // Clear cache
  getSnapshot,         // Read cached layout
  setSnapshot,         // Set custom layout
  hasSkeletonDiff,     // Detect layout changes
  walk,               // Traverse DOM tree
  classifyElement     // Classify single element
} from "skeleton-ui-loader";

License

MIT — Use freely in personal & commercial projects.


Next Steps


Made by Pavan