Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelogContact
Components
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCountry SelectCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputEmoji PickerFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime PickerTimezone SelectTree Select
Forms
Address InputBooking WidgetCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text EditorSchema Builder
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverShare DialogSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSetup ChecklistSkeletonSpinnerToast
Data Display
Approval FlowAvatarBadgeCalendar ViewCode BlockComment ThreadContact cardCountdownDescription ListDiff ViewerFile ListFile managerFolderGanttJSON ViewerKbdLog ViewerMarkdownPresenceSchedulerTagTimelineTree View
Tables & Lists
Audit LogData TableDeal PipelineEditable GridKanbanListMembers tablePermissions MatrixTableTask ListVirtual List
Charts & Stats
Animated CounterArea chartBar chartDonut chartFunnel chartGaugeGitHub ActivityHeatmap calendarLeaderboardLine chartRadar chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage compareImage CropperImage GalleryImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadChat WidgetConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Background PatternGravity LettersMarqueeTerminalText AnimateText Rotate
Mobile
Action SheetBottom Tab BarFABHaptic ButtonHero HeaderInstall PromptLarge Title HeaderNotification BannerOnboarding CarouselPicker WheelPull To RefreshSlide To ConfirmSticky CTA BarSwipe DeckSwipeable Tabs
Commerce
Cart drawerCategory pickerCheckout stepsCoupon inputFavorite buttonFilter panelListing cardListing gridOrder trackerPricePrice rangePricing tableProduct galleryQuantity stepperReviewsSeller card
Marketing Sections
App Download SectionBlog Cards SectionCTA SectionFAQ SectionFeature GridFeature ShowcaseHero SectionIntegrations SectionLogo CloudMarketing FooterMarketing HeaderMarketing SectionNewsletter SectionPricing SectionStats SectionSteps SectionTeam SectionTestimonials SectionTimeline SectionVideo Section
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAPI Keys PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowOrder History PagePost Listing WizardPricing PageProfile PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAgency PageAI Product PageAppointment Booking PageBlog PageBlog Post PageBug Bounty PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageHome Services PageImpact PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePortfolio PagePress PageProduct Tour PagePromo PageReal Estate PageReferral PageResearch Report PageRestaurant PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageStorefront PageSwitch PageTemplate Gallery PageTravel PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

Feedback

Skeleton

Feedback

Skeleton React component for Tailwind CSS v4

Setup ChecklistSpinner
Live props
Appearance
shape
radius
animation
color
highlight
Behavior
speed1x
State
loading
Layout
width
height
Code
import { Skeleton } from "@/components/ui/skeleton"

<Skeleton />
  1. Home
  2. Components
  3. Feedback
  4. Skeleton
Free

Skeleton React component for Tailwind CSS v4

v1.0.0·Added in 1.0.0

A React skeleton loader shaped like the content on its way: a shimmering block, text lines and presets for cards, lists and tables.

Nothing to press: blocks shimmer or pulse while data loads, and the real content fades in the moment loading turns off. Tap Reload in the playground to replay a 1.4s request and watch the cards swap without the layout moving. Wrap real content in a Skeleton and the block takes its exact size and corners; the wrapped content is inert while loading, so Tab skips it until it arrives. On a phone the table preset turns into one card per row. Screen readers hear each preset's label once, never every block, and reduced motion keeps every block still.

Skeleton is a free React component in the React feedback components category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add skeleton, together with UIProvider and Motion presets and the npm package motion.

Add to a project

Requirements: React 19 and Tailwind CSS v4, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup

npx wingo-ui@latest add skeleton

Usage

Import Skeleton from @/components/ui/skeleton.

import { Skeleton, SkeletonCard } from "@/components/ui/skeleton"

type Listing = { title: string; city: string; photo: string }

export function ListingCard({ listing }: { listing?: Listing }) {
  if (!listing) return <SkeletonCard label="Loading the listing" />
  return (
    <article className="flex flex-col gap-3">
      <img src={listing.photo} alt="" className="aspect-[16/10] w-full rounded-[10px] object-cover" />
      <h3 className="text-[15px] font-semibold">{listing.title}</h3>
      <p className="text-[13px] text-muted-foreground">{listing.city}</p>
    </article>
  )
}

export function Seller({ loading }: { loading: boolean }) {
  return (
    <div className="flex items-center gap-3">
      <Skeleton shape="circle" loading={loading}>
        <img src="/ana-pop.jpg" alt="Emma Carter" className="size-10 rounded-full" />
      </Skeleton>
      <Skeleton shape="line" loading={loading}>
        <p className="text-sm font-medium">Emma Carter</p>
      </Skeleton>
    </div>
  )
}

Props

  • shapedefault "rect"
    "rect" | "circle" | "line"

    rect: a block with radius (full width, 96px tall until you size it). circle: a round block, 40px unless width says otherwise. line: a 14px text line.

  • radiusdefault "md"
    "none" | "sm" | "md" | "lg" | "full"

    Corners of a rect: 0 / 6 / 10 / 16px or a pill. Circles and lines are always round. A rect wrapping real content copies the corners of what it wraps when that has any (a button, a rounded photo).

  • animationdefault "shimmer"
    "shimmer" | "pulse" | "none"

    shimmer: a soft highlight sweeps across. pulse: the block fades in and out. none: static. Under reduced motion every block stays still.

  • colordefault ""
    string

    Any CSS color for the block. Leave empty for the 5% foreground tint, which works on every surface in both themes. Set it on colored surfaces, e.g. a white tint on a brand banner.

  • highlightdefault ""
    string

    Any CSS color for the shimmer band. Leave empty for a 7% foreground tint.

  • speeddefault 1
    number

    Playback multiplier for shimmer and pulse: 0.5 is half speed, 2 twice as fast. One shimmer sweep takes 1.6s at 1, a pulse 2s. Clamped to 0.25..4.

  • loadingdefault true
    boolean

    false renders the children instead, fading them in. Content that is already there on the first render (the server's too) shows without a fade.

  • children
    ReactNode

    The real content. While loading it sits invisible and inert inside the block, so the block takes its exact size (a rect its corners too, a line draws a bar 70% as tall as the text box, like the presets); once loaded it shows in a wrapper that fades in. className lands on both, so pass layout classes like w-full or flex-1 once.

  • widthdefault ""
    number | string

    px as a number (or a number-like string such as "120"), any other CSS length as a string. rect and line fill the row by default; a circle takes its size from width, or from height when width is missing.

  • heightdefault ""
    number | string

    px as a number (or a number-like string), any other CSS length as a string. A rect is 96px tall by default, or follows an aspect-* class. Ignored by circles, which stay round.

  • className
    string

    Extra classes for the block, merged last: size it with h-4 w-32, size-12, aspect-video.

Parts

  • SkeletonText

    component

    A column of lines: 3 by default, the last at 60%. size sm / md / lg makes 10 / 14 / 18px lines (text-xs, text-sm, text-[15px]). lines={0} renders nothing. Props: { lines?: number; lastLineWidth?: number | string; size?: "sm" | "md" | "lg"; animation; speed; color; highlight; classNames?: { line } }.

  • SkeletonCard

    component

    A media card: a 16:10 block on top (media, true; mediaAspect takes any CSS aspect ratio, "1" for square thumbnails), a title and meta lines (lines, 2), a price line and a round action (footer, true). role="status" with a hidden label ("Loading"). Every preset also takes animation, speed, color and highlight. Props: { media?: boolean; mediaAspect?: string; lines?: number; footer?: boolean; radius?; label?: string; classNames?: { media, body, footer } }.

  • SkeletonList

    component

    List group rows (56px, px-4): a 40px avatar, a title and a subtitle, a button-sized action, hairlines between rows. 4 rows by default. classNames.avatar="rounded-[10px]" makes square thumbnails. Props: { rows?: number; avatar?: boolean; action?: boolean; dividers?: boolean; label?: string; classNames?: { row, avatar, action } }.

  • SkeletonTable

    component

    A table-shaped grid from 768px up (a header and 48px rows, the first column wider), one card per row below: a title line and two label / value pairs. Pure CSS, right on the first paint. 5 rows, 4 columns. Props: { rows?: number; columns?: number; header?: boolean; label?: string; classNames?: { header, row, card } }.

  • SkeletonProfile

    component

    A profile header: a cover the avatar overlaps through a round cut-out, name and meta lines, and a row of stats (3). avatarSize is in px (80). Props: { cover?: boolean; stats?: number; avatarSize?: number; radius?; label?: string; classNames?: { cover, avatar, stats } }.

Examples

Primitives

A circle and two lines for a list row, then a rect in each radius.

Text

SkeletonText with 1, 3 and 5 lines at lg, md and sm. The last line stops short, like real text.

List, then the real rows

SkeletonList in a list group swaps to the real rows after a fake 1.4s request. The rows share its rhythm, so nothing moves.

Table on every screen

A table-shaped grid from 768px up, one card per row on phones. Pure CSS, right on the first paint.

Profile

The avatar overlaps the cover through a round cut-out, so the two tints never stack into a darker patch.

Auto-size

Wrap the real content: while loading it sits invisible inside the block, which takes its exact size and corners.

Shimmer, pulse, none

A sweeping highlight, a slow fade, or a still block. Reduced motion always gets the still one.

On a colored surface

color and highlight take any CSS color, here white tints on a brand banner.

Dependencies

motionui-configmotion

Files

  • components/ui/skeleton.tsx

FAQ

Is the React Skeleton component free?

Yes. The source is free and needs no account: copy it from the Code tab or install it with the CLI.

How do I install Skeleton?

Run npx wingo-ui@latest add skeleton. It also adds the Wingo UI items it builds on (UIProvider and Motion presets) and the npm package motion. With shadcn, run npx shadcn@latest add https://wingo-ui.com/r/skeleton.json.

How does Skeleton behave on phones?

On a phone the table preset turns into one card per row.

See also

SpinnerAvatarMotion presetslib

Used in

Listing cardQR CodeMarketplace Home PageMobile App HomeKanbanFile managerImage CropperLocation MapStat CardLeaderboardData TableDeal Pipeline

and 23 more.

More React feedback components

Route ProgressEmoji ReactionAlertToastProgressBanner
All 13 React feedback components

Articles using this component

  • React Empty State Component: First Use, No Results, Errors

    Component guides · Oct 19, 2026 · 8 min read

  • React Skeleton Loader: Real Shapes, No Layout Shift

    Component guides · Oct 19, 2026 · 9 min read

PreviousSetup ChecklistNext Spinner

Primitive

<Skeleton shape="rect">

Recommended listings

Loading listings near you…

Loading the listing
Loading the listing
Loading the listing