DEV Community

Shanuka Hettiarachchi
Shanuka Hettiarachchi

Posted on

๐Ÿš€ Stop Writing Separate Skeleton Components in React

Every time we build loading states in React, we usually end up doing something like this:

if (loading) return <UserProfileSkeleton />
return <UserProfile />
Enter fullscreen mode Exit fullscreen mode

Now we have:

UserProfile
UserProfileSkeleton

  • Two components.
  • Two layouts.
  • Two things to maintain.

And when the design changes?

You update both.

Thatโ€™s duplicated UI logic.

The Real Problem

Skeleton screens are great for UX.
But maintaining them manually is painful.

  • Layout changes โ†’ update skeleton
  • Add a new field โ†’ update skeleton
  • Adjust spacing โ†’ update skeleton
  • Refactor component โ†’ update skeleton

It becomes repetitive and fragile.

What if we could generate skeleton screens automatically from the existing DOM structure?

Introducing AutoSkeleton

auto-skeleton-react lets you wrap any component and automatically generate a matching skeleton layout.

<AutoSkeleton loading={loading}>
  <UserProfile />
</AutoSkeleton>
Enter fullscreen mode Exit fullscreen mode

Thatโ€™s it.

  • No separate skeleton component.
  • No manual width/height tweaking.
  • No duplicated layout structure.

It analyzes the rendered DOM and builds a skeleton that matches your existing layout.

For 70โ€“80% of real-world use cases (dashboards, cards, forms, tables), this removes the need to build skeleton components manually.

Hereโ€™s what that looks like in practice:

AutoSkeleton Demo

๐Ÿš€ Quick example

UserProfile component

export function UserProfile() {
  return (
    <div className="flex max-w-150 gap-4 p-5">
      <Image
        src="https://avatars.githubusercontent.com/u/58282436?v=4"
        width={80}
        height={80}
        className="h-20 w-20 rounded-full"
        alt="Avatar"
      />
      <div className="flex-1">
        <h2 className="m-0 mb-2 text-2xl">Shanuka Hettiarachchi</h2>
        <p className="m-0 mb-3 text-[#666]">
          Senior Software Engineer at Wire Apps
        </p>
        <button className="cursor-pointer rounded-md border-none bg-blue-500 px-4 py-2 font-medium text-white">
          Follow
        </button>
      </div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Now let's wrap it using AutoSkeleton

<AutoSkeleton
   loading={loading}
   config={{
   animation: "pulse",
   baseColor: "#d4d4d8",
   borderRadius: 8,
   }}
>
   <UserProfile />
</AutoSkeleton>
Enter fullscreen mode Exit fullscreen mode

That's it.

๐Ÿš€ Features

Zero manual skeleton components
Wrap any React component โ€” no separate <ComponentSkeleton /> needed.

Layout preservation
Maintains flexbox, grid, margins, padding, and gaps to prevent layout shift.

Multi-line text detection
Automatically infers text line count from element height.

Table-aware rendering
Preserves semantic table structure (thead, tbody, tr, td) while skeletonizing content.

Selective opt-out
Use data-no-skeleton or .no-skeleton to keep specific elements visible during loading.

<button data-no-skeleton>Retry</button>
Enter fullscreen mode Exit fullscreen mode

Smooth transitions

Crossfades between skeleton and content for a natural UX.

Configurable

Control animation, colors, border radius, and depth limits.

โš ๏ธ When NOT to Use It

AutoSkeleton uses DOM measurement, so itโ€™s not ideal for:

  • Extremely large or virtualized lists
  • Highly dynamic layouts that constantly reflow
  • Ultra SSR-sensitive pages where zero hydration shift is required

Itโ€™s designed primarily for dashboards, SaaS apps, admin panels, and structured UIs.

Why This Exists

The real pain isnโ€™t "showing a loader".

The real pain is:

Keeping loading UI in sync with real UI without writing everything twice.

AutoSkeleton tries to remove that duplication.

If this sounds useful, give it a try:

GitHub: https://github.com/ShanukJ/auto-skeleton

NPM: https://www.npmjs.com/package/auto-skeleton-react

Docs: https://autoskeleton.shanukj.me/docs

Demo: https://autoskeleton.shanukj.me/

Iโ€™d love to hear feedback โ€” especially from production usage.

Top comments (0)