react-native-progress
Animated progress bars, circles, and pies for React Native, built on React Native SVG.
Repository Health
Technical Analysis
react-native-progress is a small, focused component library that renders animated progress indicators for React Native apps: a linear Bar, plus SVG-based Circle, Pie, and CircleSnail (an indeterminate spinner circle) built on React Native SVG. Every component shares a consistent prop surface — progress, color, indeterminate, animated — driven internally by the Animated API, so switching between shapes is a drop-in change rather than a new API to learn.
The library deliberately keeps its footprint small: only prop-types is a hard dependency, while react-native-svg is a peer dependency pulled in only by the SVG-based shapes — consumers who need just the Bar component can deep-import react-native-progress/Bar to avoid it entirely. Hand-authored TypeScript typings ship alongside the plain JavaScript source, and the project has shipped stable, incremental releases since 2015 with a maintained GitHub Actions CI pipeline running ESLint-based static analysis on every push.
What You Get
- Progress.Bar - a linear progress bar with configurable width, height, border radius, and animation type (spring, timing, or decay).
- Progress.Circle / Progress.Pie - SVG-based circular and pie-shaped progress indicators with adjustable size, thickness, stroke cap, and an optional text readout of the current percentage.
- Progress.CircleSnail - an indeterminate spinner circle that supports multi-color rainbow cycling and configurable spin/duration timing.
- Deep-importable modules - each component can be imported directly (e.g. react-native-progress/Bar) to skip pulling in the react-native-svg peer dependency when only the plain bar is needed.
- Ambient TypeScript typings - a hand-maintained index.d.ts ships with the package so consumers get typed props without installing separate @types packages.
Common Use Cases
- File upload / download progress - showing a Bar or Circle fill as a file transfer advances from 0 to 100%.
- Onboarding and loading screens - using CircleSnail as an indeterminate spinner while an app fetches initial data.
- Multi-step form or wizard progress - a Pie or Bar indicating how far a user has progressed through a checkout or setup flow.
- Media buffering indicators - a Circle or CircleSnail overlay on video/audio players to show buffering or processing state.
Under The Hood
Architecture The library is a flat collection of independent components rather than a layered system: index.js re-exports Bar, Circle, CircleSnail, and Pie, each a self-contained React class component. Bar implements its own Animated.Value-driven fill and indeterminate-sweep logic directly, while Circle, Pie, and CircleSnail share a common withAnimation higher-order component that owns the progress/rotation Animated.Value state and spin-loop logic, delegating rendering to small SVG primitive wrappers in Shapes/ (Arc, Circle, Sector) built on react-native-svg. There is no dependency injection or internal state store — state lives entirely in component instance state and Animated.Value refs — and because withAnimation is the single shared abstraction behind three of the four components, any change to its contract propagates to all of them at once.
Tech Stack The package ships as plain JSX/ES2015+ source with no build step of its own — consumers transpile it through their own React Native/Metro toolchain. prop-types is the only hard runtime dependency; react-native-svg is a peer dependency required only by the SVG-based shapes. Hand-written ambient TypeScript declarations (index.d.ts) ship alongside the JS source rather than being compiler-generated. Tooling is limited to ESLint (airbnb config) and Prettier for formatting, with a GitHub Actions workflow (tests.yml) running yarn install plus ESLint on every push and pull request, and a separate deploy.yml handling npm releases.
Code Quality
There is no dedicated unit test suite for the library itself — the CI “test” script is simply eslint *.js Shapes, i.e. static analysis rather than behavioral testing; the bundled Example/ React Native app has its own tests directory, but that exercises the example app scaffold, not the library’s components directly. Error handling is minimal and defensive (e.g. clamping progress into the 0–1 range via Math.min/Math.max) rather than explicit validation or logging. Naming is consistent (PascalCase components, camelCase internals) and PropTypes enforce prop shapes at runtime, though the TypeScript typings are hand-maintained separately from the implementation with no compiler check keeping them in sync.
What Makes It Unique The API design favors a small, memorable, shared prop surface (progress, color, indeterminate, animated) across visually different shapes, so switching from a Bar to a Circle or Pie requires no new mental model. The deep-import convention (react-native-progress/Bar) is a deliberate, explicitly documented bundle-size tradeoff letting consumers skip the react-native-svg peer dependency entirely if they only need the plain bar — an ergonomic touch uncommon in comparably small component libraries. Functionally the components implement standard, well-understood progress-indicator patterns rather than novel visual or interaction techniques.