flutter_spinkit: a catalogue of loading indicators for Flutter apps
✨ A collection of loading indicators animated with flutter. Heavily Inspired by http://tobiasahlin.com/spinkit.
At a glance
- What is it?
- One import and one widget gives you a library of loading animations, from the well known bouncing dots to a few that took a community pull request to get right.
- Who is it for?
- flutter_spinkit is good at exactly one thing, which is offering a named widget per animation so nobody has to hand write an AnimationController and a CustomPainter to fill a gap during a network call. It is good at that because the names match what the animation looks like, the constructor takes a color and a size, and the escape hatch is itemBuilder rather than a config object with thirty fields.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 107 days ago.
- What is it written in?
- Mainly Dart, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Installing the package and importing a single widget
Installation is a dependency line in `pubspec.yaml` and nothing else. The README pins the version explicitly, which is worth copying rather than guessing:
dependencies:
flutter_spinkit: ^5.2.2There is no plugin registration step, no platform channel and no native code. It is a Dart package that depends on Flutter itself, so it lands in the widget layer of an app rather than in `android/` or `ios/`. Once the dependency resolves, the whole library comes through one barrel file:
import 'package:flutter_spinkit/flutter_spinkit.dart';That single import is the entire surface area as far as setup goes. Every indicator in the package is a widget class named `SpinKit` plus the animation name, so there is nothing to configure globally and no setup callback to forget. For a package with more than three thousand stars, the install story being this short is the main reason it stays easy to adopt mid project without a migration plan.
Rendering a spinner with just a color and a size
The common case is three lines. This is the whole example the README leads with:
const spinkit = SpinKitRotatingCircle(
color: Colors.white,
size: 50.0,
);`color` and `size` are the parameters that matter for a spinner sitting in the middle of a screen. The `const` constructor is the tell that these are plain widgets with no animation state of their own to allocate, which is why the README can mark the example `const` at all.
The design decision worth noticing is that most of these indicators take the same pair. Swapping `SpinKitRotatingCircle` for `SpinKitFoldingCube` or `SpinKitPumpingHeart` does not require relearning a constructor, because the colour and size arguments stay in the same place. For a designer who wants a loading state that matches a brand, that consistency is the feature: pick the shape from the catalogue, pick the colour from the theme, and neither choice constrains the other.
Rebuilding each frame with itemBuilder
Some indicators are a single rotating shape. Others are a set of separate elements that change independently, and for those the package hands you a builder rather than a list of child widgets. The fading circle is the clearest example:
final spinkit = SpinKitFadingCircle(
itemBuilder: (BuildContext context, int index) {
return DecoratedBox(
decoration: BoxDecoration(
color: index.isEven ? Colors.red : Colors.green,
),
);
},
);The builder receives the `BuildContext` and the index of the element being drawn, and returns whatever widget that element should be at that moment. The README's example alternates red and green on the index parity, which is a demo of the mechanism rather than a look anyone would ship. What it demonstrates is that you are not locked into circles: returning an icon, a letter, or a custom shape produces a spinner built out of those things.
This is also where the package's limits show. The builder is a callback per element per frame, so a catalogue entry with a dozen elements is doing a dozen builds every tick. That is fine for a spinner, but it means these widgets are for waiting states, not for anything running continuously on screen.
Driving the animation with a controller you own
Most indicators pick a sensible default duration and let you stop there. When you need to match an animation to something else on screen, the constructor accepts your own `AnimationController`:
final spinkit = SpinKitSquareCircle(
color: Colors.white,
size: 50.0,
controller: AnimationController(vsync: this, duration: const Duration(milliseconds: 1200)),
);Passing a controller moves the `vsync` and `dispose` obligation onto the widget that owns it, which in the README's example is the enclosing `State` object. That is the trade: you get exact control over the period, so the spinner can stay in step with a page transition or a skeleton's shimmer, and you take on remembering to dispose it.
The third-party animation library this package is modelled on made the same split. The value here is that the dependency is declared in the constructor rather than in a separate object, so a widget with a controller still reads as a single `SpinKit` declaration in your build method.
What the catalogue holds and where the animations came from
The grid in the README is a set of animated GIFs with the class name under each one, and it is the best catalogue available because the class names describe the motion rather than the mood. Reading across it: `RotatingPlain`, `RotatingCircle` and `SpinningCircle` for the basic rotation family; `DoubleBounce`, `ThreeBounce`, `Pulse`, `ChasingDots` and `Wave` for the bouncing and pulsing family; `CubeGrid`, `FadingCube`, `FadingGrid`, `PulsingGrid` and `PianoWave` for the grid arrangements; and then the ones with more personality, including `PumpingHeart`, `HourGlass`, `PouringHourGlass`, `PouringHourGlassRefined`, `FoldingCube`, `WanderingCubes`, `FadingFour`, `Ring`, `Ripple`, `SpinningLines`, `DualRing` and `DancingSquare`.
Two more arrived later and are named in the release history rather than the top of the grid: `SpinKitWaveSpinner` and `PulsingGrid`, both added as contributions in v5.2.0. Counting the grid plus those additions puts the catalogue at around thirty entries.
The attribution in that grid matters for expectations. Most of the GIFs are hosted in two other people's repositories, an Android spinner collection and earlier forks of this project, and only the newer ones live in this repository's own `screenshots/` folder. So the animations are adapted from existing open source work rather than original to this package, which the README says plainly by naming Tobias Ahlin's `SpinKit` as the inspiration. The repository topics back that up: `flutter`, `animation`, `loaders`, `loading-animations` and `animation-library`, alongside the usual platform tags.
What the release notes say about correctness
Three tagged releases are listed, and the interesting content in all three is bug fixes rather than new animation ideas. v5.2.2, published on 2025-08-11, added customization options to `fading_circle`, fixed deprecated `withOpacity` usage in `SpinKitDoubleBounce`, and corrected an incorrect rotation in the `WanderingCubes` animation. v5.2.1 from 2024-03-25 removed a deprecated `format` command in favour of `dart format`, ran a quality refactor, and fixed the `SpinKitCubeGrid` animation.
That last one is worth dwelling on, because it says something about the maturity of the catalogue. A grid-based spinner had a visible rendering fault, reported as issue 80, and it took a community contribution to correct rather than a rewrite. Several entries are ports of animations written for other platforms, so a wrong rotation or a jumpy dot is a failure mode you should expect somewhere in any collection this size.
The v5.2.0 notes from 2023-05-01 also record a `setState()` called after `dispose()` fix and a jumpy dot fix in `SpinKitFadingCircle`, both of the same character: small correctness problems found by people building with the package. The repository was last pushed on 2026-06-22, which is after the v5.2.2 tag, so work continues on the branch without a new release number yet. The tree shows the usual shape for a Flutter package, with `lib/`, `test/`, `analysis_options.yaml`, a `makefile`, a `CHANGELOG.md`, and an `example/` directory that carries `android/`, `ios/`, `macos/` and `web/` targets. The example app is the thing to read, because the README points at `showcase.dart` in it as the place for anything the README does not cover.
Editorial conclusion
flutter_spinkit is good at exactly one thing, which is offering a named widget per animation so nobody has to hand write an AnimationController and a CustomPainter to fill a gap during a network call. It is good at that because the names match what the animation looks like, the constructor takes a color and a size, and the escape hatch is itemBuilder rather than a config object with thirty fields. It is not a theming system, it does not coordinate several indicators, and it does not ship skeleton screens, so a team that wants a coherent loading language across screens still has to build that layer itself. The README is thin on API surface and the `showcase.dart` file in the example directory is where the catalogue actually lives, so that file is the place to start rather than the docs page.
Frequently asked questions
How do I add flutter_spinkit to a Flutter project?
Add `flutter_spinkit: ^5.2.2` under `dependencies` in your `pubspec.yaml` and import `package:flutter_spinkit/flutter_spinkit.dart`. There is no plugin registration and no native code to configure.
How many loading animations does flutter_spinkit include?
Around thirty, based on the README grid plus the ones added later such as SpinKitWaveSpinner and PulsingGrid. They cover rotation, bouncing, fading and grid arrangements, from plain names like `Pulse` to more characterful entries like `PumpingHeart` and `PouringHourGlassRefined`.
How do I change the speed of a flutter_spinkit animation?
Pass your own `AnimationController` to the widget's `controller` parameter and set the `duration` you want. Doing so transfers the `vsync` and `dispose` responsibility to the enclosing State, so remember to dispose the controller yourself.
Can I use something other than a circle in flutter_spinkit?
Yes. Indicators built from several elements expose an `itemBuilder` callback that receives the index of each element and returns the widget to draw, so letters, icons or custom shapes can stand in for the default boxes.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/jogboms-flutter-spinkit)