The Intelligent Layout Inference Engine for Seamless Skeleton Loading
Automatically transform any UI layout into its skeleton counterpart with zero manual effort.
Writing skeleton screens is a maintenance nightmare. For every UI component you build, you usually have to write a corresponding "Skeleton" component, manually matching widths, heights, margins, and padding.
When your real UI changes, your skeletons break.
Skelon is a next-generation layout inference engine. Instead of you writing skeletons, Skelon analyzes your actual rendered components and synthesizes a pixel-perfect placeholder hierarchy in real-time.
Tip
Stop writing <Skeleton width={200} />. Simply wrap your content in <Skelon> and focus on your features.
Skelon doesn't just "guess." It uses a 10-stage geometry pipeline to detect semantic roles:
- Avatars: Detects circular containers with high border-radius.
- Text Blocks: Analyzes font-size and line-height to render matching line counts.
- Buttons: Identifies interactive elements and matches their rounded corners exactly.
- Card Layouts: Clusters related elements to maintain structural integrity.
- 60 FPS Rendering: Uses memoized layout extraction and hardware-accelerated CSS animations.
- Zero Layout Shift: By measuring the real DOM/Native nodes, Skelon ensures the "ghost" layout occupies the exact same space.
Skelon is modular and framework-agnostic at its core.
- React: Full support for React 18+ and Next.js.
- React Native: Native views and high-performance animation loops.
- CLI: Batch processing for static preset generation.
# Using pnpm (Recommended)
pnpm add @skelon/core @skelon/react
# Using npm
npm install @skelon/core @skelon/react
# Using yarn
yarn add @skelon/core @skelon/reactThe simplest way to use Skelon is to wrap your component and toggle the loading prop.
import { Skelon } from '@skelon/react';
const UserProfile = ({ user, isLoading }) => {
return (
<Skelon loading={isLoading}>
<div className="card">
<img className="avatar" src={user.image} />
<h2>{user.name}</h2>
<p>{user.description}</p>
<button>View Profile</button>
</div>
</Skelon>
);
};While Skelon is "zero-config," you can easily override detected types for specific elements using data attributes.
<div data-skelon-type="avatar">...</div> <!-- Force avatar rendering -->
<div data-skelon-type="image">...</div> <!-- Force image block -->Skelon automatically infers skeleton layouts by analyzing the rendered DOM geometry of your components.
In most cases this works with zero configuration, but some layouts may require small adjustments.
If a skeleton does not appear correctly, check the following guidelines.
Skelon detects avatars by analyzing circular geometry.
For reliable avatar detection, the element should have:
- Equal width and height
- A border-radius β₯ 50%
- A visible layout size (not
auto)
β Recommended
<img
src="/avatar.png"
style={{
width: 80,
height: 80,
borderRadius: "50%"
}}
/><img
src="/avatar.png"
style={{
width: 80,
borderRadius: "50%"
}}
/>Without an explicit height, browsers may compute it dynamically, which can prevent Skelon from correctly detecting an avatar element.
Skelon detects text blocks using layout properties such as:
font-sizeline-height- container width
Example:
<p>This is a text block that Skelon will convert into skeleton lines.</p>Ensure the element:
- is visible
- contains text content
- is not collapsed by CSS
Skelon automatically detects interactive elements such as:
button
input
select
Example:
<button>Follow</button>Skelon measures layout using:
getBoundingClientRect()
If elements are hidden or not measurable, skeleton inference may fail.
Avoid:
display: none
height: 0
collapsed containers
Ensure elements are visible and properly sized.
If automatic detection fails, you can explicitly define the skeleton type.
<div data-skelon-type="avatar"></div>
<div data-skelon-type="text"></div>
<div data-skelon-type="image"></div>
<div data-skelon-type="button"></div>This forces Skelon to render the correct skeleton shape.
Skelon works best when UI elements have clear layout geometry (explicit width, height, or flex constraints).
This allows the inference engine to generate accurate skeleton placeholders with zero layout shift.
Skelon operates using a sophisticated transformation pipeline:
graph TD
A[Raw Component Tree] --> B[Tree Extraction]
B --> C[Geometry Mapping]
C --> D[Semantic Classification]
D --> E[Clustering & Pattern Recognition]
E --> F[Shape Inference]
F --> G[Layout Synthesis]
G --> H[Final Rendering Overlay]
style H fill:#a29bfe,stroke:#6c5ce7,stroke-width:2px
Unlike naive skeleton libraries, we don't just copy classes. We measure every node's ClientBoundingRect relative to the Skelon root container, ensuring that even complex Flexbox and Grid layouts are preserved perfectly.
Our classification engine uses structural cues:
- If
borderRadius >= width / 2β‘οΈ Avatar - If
display: blockand contains text β‘οΈ TextLines - If
elementisbuttonorinputβ‘οΈ ButtonShape
For enterprise applications, use @skelon/cli to generate static presets. This removes the runtime overhead of DOM measurement for static pages.
# Scan components for structural patterns
npx skelon scan --dir ./src/components
# Generate preset files
npx skelon generate --output ./src/skelon-presets.tsIf you find Skelon useful and it has saved you hours of manual CSS work:
- β Star the repository to show your support.
- π Report issues if you find bugs or edge cases.
- π Contribute improvements by opening a Pull Request.
Together we can make Skelon the absolute standard for skeleton engine loading in the JavaScript ecosystem.
We are actively seeking maintainers for Svelte, Vue, and SolidJS adapters. Check our Contributing Guide to get started!
git clone https://github.com/ingointo/skelon.gitpnpm installpnpm test
MIT License
Copyright Β© 2026
Created by ingointo
Built for the open-source community.