Skip to content

React Native ​

react-native-loader-kit brings LoaderKit to React Native apps on Android and iOS. It runs the native engines described on this site, so you get the same built-in indicators, with the same names, params and motion, and the same progress designs.

The galleries on Built-in indicators and Progress indicators have a React Native tab: pick a design, tune it and copy the code.

Requirements ​

VersionReact NativeArchitectureMaintained on
5.x0.76 or newerNew Architecture onlymaster, npm latest
4.xsee the v4 READMENew and old architecturev4 branch, npm v4-lts

Version 5 needs the New Architecture, the default since React Native 0.76. An app built with newArchEnabled=false (Android) or RCT_NEW_ARCH_ENABLED=0 (iOS) fails at build time with a message pointing to version 4, which you install with npm install react-native-loader-kit@v4-lts.

Install ​

sh
npm install react-native-loader-kit
sh
yarn add react-native-loader-kit

The library contains native code. On iOS run cd ios && pod install, then rebuild the app.

Expo: run npx expo prebuild, then restart the project. Expo Go is not supported.

Usage ​

tsx
import { LoaderKitView } from 'react-native-loader-kit';

<LoaderKitView name="BallPulse" color="#7c3aed" style={{ width: 50, height: 50 }} />

Params change an indicator without writing a new one. Each indicator lists its params on Built-in indicators; BallPulse has count and minScale:

tsx
<LoaderKitView name="BallPulse" params={{ count: 5, minScale: 0.5 }} color="#4fc1e9" />

The indicator is drawn in a square that fills the smaller edge of the view.

Props ​

PropTypeDefaultMeaning
namebuilt-in indicator name'BallPulse'Built-in to draw. Use either name or spec
specIndicatorSpecA custom indicator, see Custom specs
paramsRecord<string, number>Param overrides. Unknown names are ignored
colorcolor'white'Color of every element
colorscolor[]One color per element, repeated when there are more elements. Wins over color
speednumber1Playback rate. Changing it never makes the animation jump
animatingbooleantruefalse freezes the current frame
hidesWhenStoppedbooleanfalseDraw nothing while animating is false
cycleProgressnumber in [0, 1]A frozen point of the animation cycle. It is not the progress of a task
reduceMotion'system' | 'never' | 'always''system'system shows a still frame when the system asks for reduced motion

Every View prop applies as well. BUILTIN_INDICATOR_NAMES lists the built-in names at runtime, and BuiltinIndicatorName is their type.

Progress indicators ​

LoaderKitProgress shows how much of a task is done: 50 designs across 10 types. Set value to a number in [0, 1], or leave it null for the indeterminate animation. New values glide along a curve that follows the rhythm of your updates and never passes the real value; smooth={false} jumps instead.

tsx
import { LoaderKitProgress } from 'react-native-loader-kit';

<LoaderKitProgress value={progress} />
<LoaderKitProgress type="linear" variant="wavy" value={progress} />
<LoaderKitProgress type="gauge" value={progress} showLabel size={64} />
<LoaderKitProgress value={null} /> {/* indeterminate */}

<LoaderKitProgress value={progress} accessibilityLabel="Uploading video">
  <StopButton onPress={cancel} />
</LoaderKitProgress>

See Types and variants for every type and the box it takes.

PropTypeDefaultMeaning
valuenumber in [0, 1] or nullnullnull shows the indeterminate animation
smoothbooleantrueGlide to new values
typeProgressType'circular'
variantProgressVariantthe first of the type
buffernumber in [0, 1]Buffered part of linear flat and wavy
sizenumber48Width of every type but linear and border
colorcoloraccent color
trackColorcolorcolor at 24% opacity
labelColorcolortext color
showLabelbooleanfalseThe percentage, inside or next to the indicator
thicknessnumberdepends on the type
trackGapnumber4Space between the progress and the track, or between segments
segmentsnumberdepends on the variantSegments, dots, ticks, steps, bars or grid columns
stopIndicatorbooleantrueDot at the end of the track of linear flat and wavy
strokeCap'round' | 'butt''round'
amplitude, wavelength, waveSpeednumber3, 40, 1 for linear; 2, 15, 1 for circularThe wave of wavy
sweepAnglenumber270Arc of gauge, in degrees
cornerRadiusnumber12Corners of border
speednumber1Playback rate of the indeterminate animation. 0 or less pauses it
reduceMotion'system' | 'never''system'system jumps to new values, stops the waves, stripes and sheens, and slows the indeterminate animation while the system asks for reduced motion

LoaderKitProgress is a View holding the drawing, which fills it, and the children, drawn above it, so every View prop applies (pointerEvents, borderRadius, onLayout and so on). The style you pass wins over the box of the type, and the drawing fits whatever box it gets: for the square types, a width and height of 120 in style give the same box as size={120}. The types with a size center their children, which suits a stop button over circular, pie and gauge; border frames them.

Screen readers announce a progress bar and its percentage. accessibilityLabel names it (default "Loading" on iOS); the children stay reachable on their own.

Custom specs ​

Experimental

Writing your own spec is experimental: until the schema is declared stable, a minor release may change it. Built-in indicators are not affected.

defineIndicator checks a spec and throws an InvalidIndicatorError that lists every problem. param refers to a param of the spec.

tsx
import { LoaderKitView, defineIndicator, param } from 'react-native-loader-kit';

const Blink = defineIndicator({
  name: 'Blink',
  duration: 0.9, // seconds per cycle
  params: { count: 4, low: 0.15 },
  layout: { type: 'row', count: param('count'), gap: 0.08 },
  shape: { type: 'rect', cornerRadius: 0.25 },
  stagger: { each: 0.15 }, // element i starts 0.15 * i seconds later
  tracks: [
    { property: 'opacity', keyTimes: [0, 0.5, 1], values: [1, param('low'), 1], easing: 'easeInOut' },
    { property: 'scaleY', keyTimes: [0, 0.5, 1], values: [1, 0.5, 1], easing: 'easeInOut' },
  ],
});

<LoaderKitView spec={Blink} params={{ count: 6 }} color="white" style={{ width: 60, height: 60 }} />

Define specs outside of components, or memoize them: a new spec object restarts the animation. validate(spec) returns the same list of problems without throwing. See Custom indicators for the format; the same spec runs in native Android, iOS, macOS and Windows apps and on the web.

Migrating from version 4 ​

  • The New Architecture is required, see Requirements.
  • animationSpeedMultiplier is now speed.
  • IndicatorName is now BuiltinIndicatorName, and ALL_INDICATORS is BUILTIN_INDICATOR_NAMES.
  • CommonIndicatorName, IOSOnlyIndicatorName, COMMON_INDICATORS, IOS_ONLY_INDICATORS, isIndicatorAvailableOnPlatform and getAvailableIndicators are gone: every indicator works on both platforms. BallRotateChase and CircleStrokeSpin, which were iOS only, now work on Android too.
  • The indicator names are unchanged.
  • On Android the indicators no longer come from AVLoadingIndicatorView, so their timing now matches iOS: easing curves, keyframe times, start delays and density-independent sizes.

Troubleshooting ​

uses-sdk:minSdkVersion XX cannot be smaller than version YY ​

LoaderKit needs minSdkVersion 24. The library reads minSdkVersion, compileSdkVersion, targetSdkVersion and kotlinVersion from the ext block of your android/build.gradle, as the React Native template defines them, so raise minSdkVersion there:

groovy
buildscript {
    ext {
        minSdkVersion = 24
        compileSdkVersion = 35
        targetSdkVersion = 35
        kotlinVersion = "2.0.21"
    }
}

See also ​

Released under the MIT License.