This is documentation for the next SDK version. For up-to-date documentation, see the latest version (SDK 56).
LoadingIndicator
Jetpack Compose loading indicator components for displaying loading state.
For the complete documentation index, see llms.txt. Use this file to discover all available pages.
Expo UI Loading Indicators match the official Jetpack Compose Loading Indicator API.

Installation
- npx expo install @expo/uiIf you are installing this in an existing React Native app, make sure to install expo in your project.
Usage
Loading indicator
A morphing-shape loading animation from Material 3 Expressive.
import { Host, LoadingIndicator } from '@expo/ui/jetpack-compose'; export default function LoadingIndicatorExample() { return ( <Host matchContents> <LoadingIndicator /> </Host> ); }
Contained loading indicator
A loading indicator inside a colored background.
import { Host, ContainedLoadingIndicator } from '@expo/ui/jetpack-compose'; export default function ContainedLoadingIndicatorExample() { return ( <Host matchContents> <ContainedLoadingIndicator /> </Host> ); }
Indeterminate
Omit the progress prop to animate continuously without indicating a specific completion level.
import { ContainedLoadingIndicator, Host, LoadingIndicator, Row } from '@expo/ui/jetpack-compose'; export default function IndeterminateExample() { return ( <Host matchContents> <Row horizontalArrangement={{ spacedBy: 16 }}> <LoadingIndicator /> <ContainedLoadingIndicator /> </Row> </Host> ); }
Determinate
Pass an observable state from useNativeState as progress. Update progress.value between 0 and 1.
import { ContainedLoadingIndicator, Host, LoadingIndicator, Row, useNativeState, } from '@expo/ui/jetpack-compose'; import { useEffect } from 'react'; export default function DeterminateExample() { const progress = useNativeState(0); useEffect(() => { const interval = setInterval(() => { progress.value = (progress.value + 0.05) % 1; }, 500); return () => clearInterval(interval); }, [progress]); return ( <Host matchContents> <Row horizontalArrangement={{ spacedBy: 16 }}> <LoadingIndicator progress={progress} /> <ContainedLoadingIndicator progress={progress} /> </Row> </Host> ); }
API
import { LoadingIndicator, ContainedLoadingIndicator } from '@expo/ui/jetpack-compose';
Components
Type: React.Element<ComponentType<ContainedLoadingIndicatorProps>>
A loading indicator that displays loading using morphing shapes inside a container.
Matches the Jetpack Compose ContainedLoadingIndicator.
Type: React.Element<ComponentType<LoadingIndicatorCommonConfig>>
A loading indicator that displays loading using morphing shapes.
Matches the Jetpack Compose LoadingIndicator.
Types
Common props shared by loading indicator variants.
| Property | Type | Description |
|---|---|---|
| color(optional) | ColorValue | Loading indicator color. |
| modifiers(optional) | ModifierConfig[] | Modifiers for the component. |
| progress(optional) | ObservableState<number | null> | An observable state that holds the current progress value.
Create one with |
Observable state shared between JavaScript and native views (Jetpack Compose on Android and SwiftUI on iOS).
Type: SharedObject extended by:
| Property | Type | Description |
|---|---|---|
| onChange | [listener] | null | A single listener invoked on the native UI runtime whenever the value changes
(after iOS The callback must be a worklet so it can run synchronously on the UI thread.
Attach it inside Example
|
| value | T | The current value. Writes from a UI worklet are synchronous and immediately readable. Writes from the JS thread are scheduled to the UI thread asynchronously, the new value is not readable until the update has been applied. Prefer writing from a worklet when you need synchronous updates |