askill
loading-state-patterns

loading-state-patternsSafety 100Repository

Patterns for skeleton loaders, shimmer effects, and loading states that match design system aesthetics. Covers skeleton components, shimmer animations, and progressive loading. Use when building polished loading experiences. Triggers on skeleton, loading state, shimmer, placeholder, loading animation.

0 stars
1.2k downloads
Updated 2/12/2026

Package Files

Loading files...
SKILL.md

Loading State Patterns

Build loading states that feel intentional and match your design system aesthetic.


When to Use

  • Building skeleton loaders for content areas
  • Need shimmer effects for streaming content
  • Want progressive loading experiences
  • Building premium loading UX

Pattern 1: Skeleton Base

import { cn } from '@/lib/utils';

interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {
  shimmer?: boolean;
}

export function Skeleton({ className, shimmer = true, ...props }: SkeletonProps) {
  return (
    <div
      className={cn(
        'rounded-md bg-muted',
        shimmer && 'animate-shimmer bg-gradient-to-r from-muted via-muted-foreground/10 to-muted bg-[length:200%_100%]',
        className
      )}
      {...props}
    />
  );
}

CSS Animation

@keyframes shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

.animate-shimmer {
  animation: shimmer 1.5s ease-in-out infinite;
}

Pattern 2: Content Skeleton Layouts

Card Skeleton

export function CardSkeleton() {
  return (
    <div className="rounded-lg border bg-card p-4 space-y-3">
      <div className="flex items-center gap-3">
        <Skeleton className="size-10 rounded-full" />
        <div className="space-y-1.5 flex-1">
          <Skeleton className="h-4 w-1/3" />
          <Skeleton className="h-3 w-1/4" />
        </div>
      </div>
      <Skeleton className="h-20 w-full" />
      <div className="flex gap-2">
        <Skeleton className="h-8 w-20" />
        <Skeleton className="h-8 w-20" />
      </div>
    </div>
  );
}

Table Row Skeleton

export function TableRowSkeleton({ columns = 4 }: { columns?: number }) {
  return (
    <tr>
      {Array.from({ length: columns }).map((_, i) => (
        <td key={i} className="p-3">
          <Skeleton className="h-4 w-full" />
        </td>
      ))}
    </tr>
  );
}

Metric Skeleton

export function MetricSkeleton() {
  return (
    <div className="space-y-2">
      <Skeleton className="h-3 w-16" />
      <Skeleton className="h-8 w-24" />
    </div>
  );
}

Pattern 3: Design System Skeleton

Match skeleton to your aesthetic:

// For retro-futuristic theme
export function CyberSkeleton({ className, ...props }: SkeletonProps) {
  return (
    <div
      className={cn(
        'rounded-md bg-tone-cadet/30',
        'animate-pulse-glow',
        'border border-tone-cyan/10',
        className
      )}
      {...props}
    />
  );
}

// CSS
@keyframes pulse-glow {
  0%, 100% { opacity: 0.4; box-shadow: 0 0 0 0 rgba(var(--tone-cyan), 0); }
  50% { opacity: 0.6; box-shadow: 0 0 8px 0 rgba(var(--tone-cyan), 0.1); }
}

Pattern 4: Progressive Loading

Show content as it loads:

interface ProgressiveLoadProps {
  isLoading: boolean;
  skeleton: React.ReactNode;
  children: React.ReactNode;
}

export function ProgressiveLoad({
  isLoading,
  skeleton,
  children,
}: ProgressiveLoadProps) {
  return (
    <div className="relative">
      {isLoading ? (
        skeleton
      ) : (
        <motion.div
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          transition={{ duration: 0.2 }}
        >
          {children}
        </motion.div>
      )}
    </div>
  );
}

Pattern 5: Streaming Content Indicator

For AI/LLM content that streams:

export function StreamingIndicator() {
  return (
    <div className="flex items-center gap-1">
      {[0, 1, 2].map((i) => (
        <motion.div
          key={i}
          className="size-1.5 rounded-full bg-primary"
          animate={{ scale: [1, 1.3, 1], opacity: [0.5, 1, 0.5] }}
          transition={{
            duration: 0.8,
            repeat: Infinity,
            delay: i * 0.15,
          }}
        />
      ))}
    </div>
  );
}

Pattern 6: Loading Progress Bar

interface LoadingProgressProps {
  progress?: number; // 0-100, undefined = indeterminate
}

export function LoadingProgress({ progress }: LoadingProgressProps) {
  const isIndeterminate = progress === undefined;

  return (
    <div className="h-1 w-full bg-muted overflow-hidden rounded-full">
      <div
        className={cn(
          'h-full bg-primary transition-all duration-300',
          isIndeterminate && 'animate-indeterminate'
        )}
        style={!isIndeterminate ? { width: `${progress}%` } : undefined}
      />
    </div>
  );
}

// CSS
@keyframes indeterminate {
  0% { transform: translateX(-100%); width: 50%; }
  100% { transform: translateX(200%); width: 50%; }
}

.animate-indeterminate {
  animation: indeterminate 1.5s ease-in-out infinite;
}

Pattern 7: Skeleton Grid

export function GridSkeleton({ 
  count = 6, 
  columns = 3 
}: { 
  count?: number; 
  columns?: number;
}) {
  return (
    <div 
      className="grid gap-4" 
      style={{ gridTemplateColumns: `repeat(${columns}, 1fr)` }}
    >
      {Array.from({ length: count }).map((_, i) => (
        <CardSkeleton key={i} />
      ))}
    </div>
  );
}

Related Skills


NEVER Do

  • Use gray skeletons on dark themes — Match your surface colors
  • Skip shimmer animation — Static blocks look broken
  • Make skeletons exact size — Slight size variation is natural
  • Forget aspect ratios — Images need consistent skeleton ratios
  • Show skeleton forever — Add timeout fallbacks for errors

Quick Reference

// Basic skeleton
<Skeleton className="h-4 w-full" />

// Avatar skeleton
<Skeleton className="size-10 rounded-full" />

// Text lines
<div className="space-y-2">
  <Skeleton className="h-4 w-3/4" />
  <Skeleton className="h-4 w-1/2" />
</div>

// Card skeleton
<div className="p-4 space-y-3">
  <Skeleton className="h-6 w-1/3" />
  <Skeleton className="h-20 w-full" />
</div>

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

88/100Analyzed 2/19/2026

Comprehensive skill covering 7 loading state patterns with clear code examples, CSS animations, and practical guidance. Well-organized with "When to Use" section, quick reference, and NEVER Do guidelines. Slight penalty for mismatched tags (ci-cd, github-actions, llm, observability don't relate to loading states). High reusability across projects. Located in dedicated skills folder which is appropriate.

100
88
85
92
90

Metadata

Licenseunknown
Version-
Updated2/12/2026
Publishervibekit-apps

Tags

ci-cdgithub-actionsllmobservability