shimmerkit

June 28, 2026 · View on GitHub

Zero-dependency, framework-agnostic animated loaders & skeleton placeholders. One tuned engine — drops into React, Vue, Svelte, or plain HTML. Accessible by default.

CI npm downloads bundle size license

🔗 Live demo — play with every loader & skeleton, tweak color, size, and speed.

22 curated, hand-tuned loaders + 10 skeleton presets. No SVG, no JS animation loop — just CSS that scales with currentColor and a couple of custom properties. The exact same visuals everywhere because every renderer reads from one shared engine.

spinner · dots · bars · pulse · ring · ripple · wave · grid · orbit · bounce
conic · comet · blob · wobble · bouncer · liquid · muncher · wifi · helix · cube · folding · inchworm

Why

In an AI-everywhere world you can vibe-code a one-off spinner. What you don't want to redo each time is the boring part: cross-browser tuning, staggered keyframe delays, prefers-reduced-motion, screen-reader labels, and shipping it identically to React and vanilla. shimmerkit is that drop-in.

  • 🪶 Zero dependencies, tiny, tree-shakeable
  • 🧩 Framework-agnostic — native Web Components work in Vue/Svelte/Angular/HTML
  • ⚛️ First-class React wrapper (SSR-safe, renders real DOM)
  • Accessiblerole="status", labels, graceful reduced-motion fallback
  • 🎨 Themeable with color, size, speed, thickness (or raw CSS variables)

Install

npm i shimmerkit

React

import { Loader, Skeleton } from "shimmerkit/react";

function Example() {
  return (
    <>
      <Loader variant="ring" size={48} color="#6366f1" />

      {loading ? (
        <Skeleton variant="card" />
      ) : (
        <Article data={data} />
      )}
    </>
  );
}

Styles auto-inject on the client. For zero-flash SSR, also import the stylesheet once:

import "shimmerkit/styles.css";

Vanilla / Web Components

No build step, no framework. Import the package once to register the <shk-loader> and <shk-skeleton> custom elements, then use them anywhere — including inside Vue, Svelte, and Angular templates (they're just custom elements).

<script type="module">
  import "shimmerkit"; // registers <shk-loader> and <shk-skeleton>
</script>

<!-- Loaders -->
<shk-loader variant="ring" size="48" color="#6366f1"></shk-loader>
<shk-loader variant="dots" size="56" color="tomato" speed="1.4"></shk-loader>

<!-- Skeletons -->
<shk-skeleton variant="text" lines="3"></shk-skeleton>
<shk-skeleton variant="circle" width="48"></shk-skeleton>
<shk-skeleton variant="card"></shk-skeleton>

Using a CDN? Pull the ESM build straight from a module CDN — no install, no bundler. The Web Components register on import and inject their own styles, so this snippet is fully self-contained:

<script type="module">
  import "https://cdn.jsdelivr.net/npm/shimmerkit@0.1.0/+esm";
</script>

<shk-loader variant="ring" size="48" color="#6366f1"></shk-loader>
<shk-skeleton variant="card"></shk-skeleton>

Other CDNs work too — https://unpkg.com/shimmerkit@0.1.0 or https://esm.sh/shimmerkit@0.1.0. Pin a version (@0.1.0) so examples don't drift on future releases.

Avoid flashing on fast loads

Pass delay (ms) and the loader/skeleton stays hidden until that time elapses — if your data arrives first, nothing ever flashes:

<Loader variant="ring" delay={150} />
<Skeleton variant="list" count={5} delay={150} />
<shk-loader variant="ring" delay="150"></shk-loader>

API

Loader

Prop / attributeTypeDefault
variantspinner · dots · bars · pulse · ring · ripple · wave · grid · orbit · bounce · conic · comet · blob · wobble · bouncer · liquid · muncher · wifi · helix · cube · folding · inchwormspinner
sizenumber (px) | CSS length40
colorany CSS colorcurrentColor
speednumber multiplier (2 = twice as fast)1
thicknessnumber (px) | CSS length — ring/spinner/ripple stroke10% of size
labelstring — screen-reader textLoading
delaynumber (ms) — wait before showing, to avoid flashing on fast loads0

Skeleton

Prop / attributeTypeDefault
varianttext · circle · rect · card · avatar · list · table · button · image · gridtext
linesnumber — lines (text) or rows (table)3
countnumber — items for list / grid4 / 6
columnsnumber — columns for table3
widthnumber (px) | CSS length
heightnumber (px) | CSS length
radiusnumber (px) | CSS length8
speednumber multiplier1
delaynumber (ms) — wait before showing0

Theming with CSS variables

Everything is driven by currentColor plus a few custom properties, so you can theme without props:

.my-loader {
  color: hotpink;
  --shk-size: 64px;
  --shk-speed: 1.5;
}

Develop

npm install
npm run build      # bundles ESM + CJS + types, emits styles.css
npm test           # vitest
npm run demo       # build + open http://localhost:5173

License

MIT