Skeleton loading screens in React Native
By the LumioUI team · Updated
A skeleton screen shows dim blocks in the exact shape of the content that's loading. The page holds its layout, and nothing jumps when the data arrives. In React Native that's a few Views with a muted background, swapped for the real content once it's ready. The LumioUI Skeleton shapes the blocks with classes, and SkeletonSwitch switches the content on in their place.
Live demo of the LumioUI Skeleton component. It's interactive, so try it.
How to build a skeleton screen
- Match the layout. Each placeholder takes the size and corner radius of what will replace it: a circle for the avatar, short and long lines for the text. If the skeleton doesn't match, the swap still shifts the page.
- Keep it muted. Use a low-contrast block that reads in light and dark mode, such as a semi-transparent grey or a theme "muted" colour.
- Swap, don't stack. Render the placeholder until the data is there, then the content in the same spot. A short fade helps, but the content shouldn't slide in from somewhere else.
- Accessibility. Group the placeholder and label it "Loading…" so screen readers announce one thing, not a dozen empty boxes.
import { View } from "react-native";
// A placeholder is just a dim block in the shape of what's coming.
export function Bone({ w, h, r = 8 }: { w: number | string; h: number; r?: number }) {
return <View style={{ width: w, height: h, borderRadius: r, backgroundColor: "rgba(127,127,127,.18)" }} />;
}
export function PostSkeleton() {
return (
<View style={{ flexDirection: "row", gap: 12 }} accessibilityLabel="Loading post" accessible>
<Bone w={40} h={40} r={20} />
<View style={{ flex: 1, gap: 8 }}>
<Bone w="40%" h={14} />
<Bone w="90%" h={12} />
<Bone w="70%" h={12} />
</View>
</View>
);
} Shimmer or still?
Many apps sweep a shimmer gradient across their skeletons. It does say "loading", but it's constant motion in the corner of the eye. It costs battery and frame time on long lists, and people with motion sensitivity notice it. A still, dim block that switches on when the content arrives feels calmer and keeps the frame rate free for scrolling. LumioUI's skeletons are still by design. If your product needs a shimmer, add it to a few hero placeholders, not to every row.
The quick way: LumioUI Skeleton
Skeleton is one dim block you shape with NativeWind classes. SkeletonSwitch renders the placeholder until loaded is true, then switches the content on in its place, row by row. It's free and runs in Expo Go.
import { View } from "react-native";
import { Skeleton, SkeletonSwitch } from "@/components/ui/skeleton/skeleton";
import { PostRow, type PostData } from "./PostRow";
export function Post({ post }: { post?: PostData }) {
return (
<SkeletonSwitch
loaded={!!post}
placeholder={
<View className="flex-row gap-3">
<Skeleton className="h-10 w-10 rounded-full" />
<View className="flex-1 gap-2">
<Skeleton className="h-3.5 w-2/5 rounded-md" />
<Skeleton className="h-3 w-11/12 rounded-md" />
<Skeleton className="h-3 w-3/4 rounded-md" />
</View>
</View>
}
>
{post && <PostRow post={post} />}
</SkeletonSwitch>
);
} - Shape each block with classes: height, width,
rounded-fullfor avatars. SkeletonSwitchtakesloaded, aplaceholderand the real content aschildren.- For a whole page with no data yet, use Empty State. For an action in progress, use a Loader.
Add it to your app
LumioUI's CLI copies the component's source into your project, so it's yours to read and change. Run init once per project:
npx @lumioui/cli init
npx @lumioui/cli add skeleton It works in Expo (SDK 54+) and bare React Native, with Reanimated 4 and NativeWind. See the installation guide and the full Skeleton API.
Related components
More React Native guides
- How to make a bottom sheet in React Native
- Animated tabs with a sliding indicator in React Native
- How to show toast notifications in React Native
- How to add dark mode and a theme toggle in React Native
- How to build an accordion in React Native
- How to make a side drawer menu in React Native
- How to make an animated heart like button in React Native
- How to make a modal dialog in React Native
- How to build an animated carousel in React Native
- How to make an animated splash screen in React Native and Expo
- How to build a month calendar in React Native