Skeleton

Skeleton is the shape-preserving loading placeholder.
Use it when the layout is already known but the real data has not arrived yet. A skeleton helps the screen feel stable because the user can see where content will appear, even before the text or image is ready.

Example

use fission::prelude::*;

let widget: Widget = VStack {
    spacing: Some(12.0),
    children: vec![
        Skeleton {
            id: WidgetId::explicit("profile_avatar_loading"),
            width: Some(48.0),
            height: Some(48.0),
            circle: true,
            animated: true,
        }
        .into(),
        Skeleton {
            id: WidgetId::explicit("profile_name_loading"),
            width: Some(180.0),
            height: Some(18.0),
            circle: false,
            animated: true,
        }
        .into(),
    ],
}
.into();
This keeps the loading state close to the final layout instead of replacing everything with a generic spinner.

Field table

Field
Type
Meaning
Notes / default behavior
id
WidgetId
Stable identity used for animation state.
Required. Give each skeleton a unique id.
width
Option<f32>
Placeholder width.
Defaults to 100.0.
height
Option<f32>
Placeholder height.
Defaults to 20.0.
circle
bool
Whether to render the placeholder as a fully rounded shape.
Defaults to false. Useful for avatar placeholders.
animated
bool
Whether the placeholder should pulse in opacity.
Defaults to true.

User experience guidance

A skeleton is best when you know the final shape of the content. If you have no idea what will load or when, a more generic loading treatment may be more honest.
The checked-in widget animates opacity when animated is true, so stable ids matter. If the id changes every build, the animation state cannot behave predictably.

Specific advice

Match the skeleton shape to the eventual content as closely as is practical. A loading state feels more polished when the placeholder predicts the final layout instead of using random bars everywhere.

Production checklist

For Skeleton, review the fields that change behavior before treating the widget as finished: id, width, height, circle, animated. The goal is to make the product rule visible in state and actions, not hidden inside ad-hoc construction code.
If this widget appears inside an interactive flow, keep the surrounding action binding in the parent component and test that the flow still has one clear reducer path.
Set id only when identity must be stable across filtering, reordering, diagnostics, or tests; otherwise let Fission derive identity from structure.
Check the semantics tree for the user-facing label or role that makes this widget understandable without relying only on pixels.
Prefer parent layout and design-system sizing first; use explicit size or spacing fields when the product layout requires that constraint on this widget specifically.
Add at least one component or harness test that confirms the visible text, semantic role, action dispatch, and layout constraint that matter for this widget in context.
If a screen starts repeating the same Skeleton setup, extract a named component around this widget. That keeps the reference API small while making product code easier to read and safer for generated code to copy.
Spinner, CircularProgress, Card, and Avatar.
Fission
A cross-platform, GPU-accelerated user interface framework for Rust. MIT licensed.
Copyright (c) 2026 Fission
Ready to use today. Widget APIs are expected to remain stable; some runtime and shell APIs may change before 1.0.0.
Fission 0.7.0