Skeleton

A placeholder component used to indicate loading content. Skeletons mimic the shape and layout of actual content while data is being fetched.

Docs
import { Skeleton } from "~/components/skeleton";

export default function SkeletonBasicDemo() {
  return <Skeleton class="h-4 w-[250px]" />;
}

Installation

CLI

Run the following command to add the component to your project:

npx @ark-preset/cli@latest add skeleton

Manual

Create the recipe file at src/components/recipes/skeleton.ts:

import { tv, type VariantProps } from "tailwind-variants";

export const skeletonVariants = tv({
  base: "animate-pulse rounded-md bg-muted",
});

export type SkeletonVariants = VariantProps<typeof skeletonVariants>;

Create the component file at src/components/skeleton/index.tsx:

import { splitProps, type Component } from "solid-js";
import { skeletonVariants } from "../recipes/skeleton";
import { ark, type HTMLArkProps } from "@ark-ui/solid/factory";

type SkeletonProps = HTMLArkProps<"div">;

const Skeleton: Component<SkeletonProps> = (props) => {
  const [local, others] = splitProps(props, ["class"]);
  return <ark.div class={skeletonVariants({ class: local.class })} {...others} />;
};

export { Skeleton, skeletonVariants };

Note: Make sure your project has the Tailwind CSS theme variables set up (--background, --foreground, --ring, --border, etc.) or override the utility classes to match your design system.

Usage

Basic Usage

import { Skeleton } from "~/components/skeleton";

export default function SkeletonBasicDemo() {
  return <Skeleton class="h-4 w-[250px]" />;
}

Avatar Placeholder

Use a circular skeleton as a placeholder for an avatar while loading.

import { Skeleton } from "~/components/skeleton";

export default function SkeletonAvatarDemo() {
  return (
    <div class="flex items-center gap-4">
      <Skeleton class="size-10 rounded-full" />
      <div class="flex flex-col gap-2">
        <Skeleton class="h-4 w-[200px]" />
        <Skeleton class="h-3 w-[160px]" />
      </div>
    </div>
  );
}

Card Skeleton

Combine multiple skeleton elements to create a card loading placeholder.

import { Skeleton } from "~/components/skeleton";

export default function SkeletonCardDemo() {
  return (
    <div class="flex flex-col gap-3 rounded-lg border border-border p-4">
      <Skeleton class="h-5 w-[250px]" />
      <Skeleton class="h-4 w-full" />
      <Skeleton class="h-4 w-[80%]" />
      <div class="flex gap-2 pt-2">
        <Skeleton class="h-8 w-20" />
        <Skeleton class="h-8 w-20" />
      </div>
    </div>
  );
}

Customizing

The skeleton is a simple <div> with animate-pulse and bg-muted applied. Use class to control dimensions and shape:

import { Skeleton } from "~/components/skeleton";

export default function SkeletonCustomizingDemo() {
  return (
    <div class="flex flex-col gap-4">
      {/* Circle for avatars */}
      <Skeleton class="size-10 rounded-full" />

      {/* Text line */}
      <Skeleton class="h-4 w-[250px]" />

      {/* Button placeholder */}
      <Skeleton class="h-9 w-24 rounded-md" />

      {/* Full-width card */}
      <Skeleton class="h-32 w-full rounded-xl" />
    </div>
  );
}

API Reference

PropTypeDefault
classstring
childrenany