skelit-loader
v1.1.0
Published
Zero-config DOM-cloning skeleton loader. Works with Vanilla JS, React, and TypeScript.
Maintainers
Readme
Skelit
Skelit is a zero-config DOM-cloning skeleton loader that automatically mirrors your real page layout.
Unlike traditional skeleton libraries that require you to manually draw, position, and maintain absolute-positioned gray shapes, Skelit clones your existing HTML elements, classifies them, and applies a smooth shimmer overlay directly on top.
Your CSS grid, flexbox layout, padding, margins, media queries, and responsive design are preserved exactly because the structure is identical.
Features in Detail
Skelit comes packed with features designed to build beautiful, modern, and zero-effort skeleton loaders:
True DOM Cloning Instead of drawing approximate placeholders, Skelit performs a deep clone of your targeted DOM element. This ensures that your layout structures (Flexbox, Grid, nested margins, paddings, and alignment rules) are replicated 1:1.
Smart Element Classifier Skelit traverses the DOM tree and automatically detects the semantic purpose of each element to style it correctly:
- Text Blocks: Elements containing direct text are replaced with simulated skeleton lines. If there are multiple lines of text, it creates a flex column of lines and randomly shortens the last line for a highly realistic paragraph look.
- Circular Profile Images: Any element styled with
border-radius: 50%,border-radius: 999px, or square blocks with high curvature are converted into circular shimmer indicators. - Images: Image elements (
<img>,video,svg,canvas) are styled as box placeholders. Skelit automatically strips their original content and sets theirsrcto a transparent 1x1 base64 GIF to prevent browsers from showing a broken image icon. - Buttons & Action Items: HTML
<button>tags, input buttons (submit/button), ARIArole="button"elements, and styled block links are turned into button skeleton blocks. - Form Fields:
<input>,<textarea>, and<select>tags are converted into input skeleton blocks. Skelit clears any activevalueandplaceholderattributes so they don't overlay on the shimmer. - Containers: Layout divs, cards, grids, and other structural containers are kept transparent and clean so they preserve the document structure.
Flexible Scope Targeting
- Full-Page Viewport: Run
Skelit.show()to cover the entire page. Skelit automatically handles viewport locking, scroll synchronization, and overlays the page. - Container Scope: Run
Skelit.show(container)to overlay only that container. Skelit automatically creates an absolute overlay and scopes it to the container's boundaries without affecting other components.
- Full-Page Viewport: Run
Hardware-Accelerated Animations
- Linear Shimmer Sweep: Uses a high-contrast
120degdiagonal linear gradient (#e2e8f0to#f8fafc) moving smoothly at a constant speed to create an attractive, modern shimmer sweep. - Overlay Fade-In: Fades the skeleton overlay in smoothly over
200ms(ease-out). - Overlay Fade-Out: Fades the skeleton overlay out smoothly over
150ms(ease-in) before removing it from the DOM to prevent abrupt flashes.
- Linear Shimmer Sweep: Uses a high-contrast
React Component & Hooks Integration Skelit offers hooks (
useSkelit,useSkelitPage) and a wrapper (SkelitWrapper) to manage DOM mounting, requestAnimationFrame paint scheduling, and lifecycle unmounting cleanly.
Installation
Install via npm, yarn, or pnpm:
npm install skelit-loader
# or
yarn add skelit-loader
# or
pnpm add skelit-loaderOr import directly in your HTML using a CDN (no bundler required):
<script src="https://unpkg.com/skelit-loader/dist/skelit.umd.js"></script>General Syntax
1. Vanilla JS Usage
import Skelit from 'skelit-loader';
// Show full page skeleton
Skelit.show();
// Show container skeleton
const myContainer = document.getElementById('my-card');
Skelit.show(myContainer, { timeout: 3000 }); // Auto-hide after 3 seconds
// Hide the active skeleton manually
Skelit.hide();2. React Hooks Usage
import { useSkelit, useSkelitPage, SkelitWrapper } from 'skelit-loader/react';
// Hook A: Target container
const { ref } = useSkelit(isLoading);
// Hook B: Target full page
useSkelitPage(isLoading);
// Component C: Wrapper component
<SkelitWrapper loading={isLoading}>
<div>Content to skeletonize</div>
</SkelitWrapper>Detailed Examples
Vanilla JS + Fetch API
import Skelit from 'skelit-loader';
async function fetchUserData() {
const container = document.querySelector('.profile-container');
// Show skeleton over the profile container while loading
Skelit.show(container);
try {
const response = await fetch('/api/user/profile');
const data = await response.json();
renderProfile(data);
} catch (error) {
console.error("Failed loading profile", error);
} finally {
// Hide the skeleton when finished
Skelit.hide();
}
}React Hook Example (useSkelit)
import React, { useState, useEffect } from 'react';
import { useSkelit } from 'skelit-loader/react';
function UserCard() {
const [loading, setLoading] = useState(true);
const [userData, setUserData] = useState(null);
// Bind ref to the target container
const { ref } = useSkelit(loading);
useEffect(() => {
fetch('/api/user')
.then(res => res.json())
.then(data => {
setUserData(data);
setLoading(false);
});
}, []);
return (
<div ref={ref} className="user-card" style={{ padding: '16px', display: 'flex', gap: '12px' }}>
<img src={userData?.avatar} className="avatar" style={{ width: '48px', height: '48px', borderRadius: '50%' }} />
<div>
<h4>{userData?.name}</h4>
<p>{userData?.bio}</p>
</div>
</div>
);
}API Reference
Skelit.show(root?, options?)
Mounts the skeleton loader overlay.
- Syntax:
Skelit.show(root?: Element | null, options?: SkelitOptions): void - Parameters:
root(Element | null, optional): The container DOM element. Defaults todocument.body(full-page loader).options(SkelitOptions, optional):timeout(number): Automatically callhide()after N milliseconds.
Skelit.hide()
Fades out and removes the active skeleton overlay, restoring any overridden layout styles.
- Syntax:
Skelit.hide(): void
React API Reference
[!NOTE] All React hooks and components are exported with two naming styles: Branded (
useSkelit,useSkelitPage,SkelitWrapper) and Standard (useSkeleton,useSkeletonPage,SkeletonWrapper). You can import and use whichever style you prefer.
useSkelit(loading) / useSkeleton(loading)
Hook for targeting a specific component/element.
- Syntax:
useSkelit(loading: boolean): { ref: React.RefObject<any> } - Returns: An object with a
refthat you must attach to your container element.
useSkelitPage(loading) / useSkeletonPage(loading)
Hook for skeletonizing the full viewport (document.body).
- Syntax:
useSkelitPage(loading: boolean): void
<SkelitWrapper> / <SkeletonWrapper>
A wrapper component that creates a relative container and overlays a skeleton during loading states.
- Props:
loading(boolean): Renders the skeleton overlay whentrue, shows the real children whenfalse.children(React.ReactNode): The actual UI components that you want to skeletonize.
Customizing Shimmer Styles
Skelit injects CSS variables and keyframes automatically. You can easily customize the shimmer color, speed, and contrast in your own global stylesheet:
/* Custom Shimmer Theme */
:root {
/* Customize the gradient colors (base -> highlight -> base) */
--sk-base-color: #f1f5f9; /* Tailwind slate-100 */
--sk-highlight-color: #ffffff; /* White */
/* Shimmer sweep duration */
--sk-shimmer-duration: 1.8s;
}
/* Optional: Override styles directly on classes if needed */
.__sk-block {
animation-duration: var(--sk-shimmer-duration) !important;
}License
MIT © Aatif Alam
