Library / SDK
dalerank/imspinner avatar
dalerank/imspinner

imspinner: a header-only set of loading spinners for Dear ImGui

Set of nice spinners for imgui

609 stars48 forksC++MIT

At a glance

What is it?
imspinner is a MIT licensed, header-only C++ library that draws loading spinners inside Dear ImGui windows, split across separate headers by spinner family so you compile only what you use. The catalogue is large, the integration is a copied file, and the documentation is thin.
Who is it for?
imspinner suits Dear ImGui developers who want a polished loading indicator without writing their own draw calls, and who are happy to copy a handful of header files into a project. It does not suit a build that wants a packaged dependency, since the repository carries no build files or package manifest and the include paths in the examples assume the headers sit next to your sources, and it does not suit a project without Dear ImGui, which it does not vendor.
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 11 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A spinner set that compiles into your ImGui build

imspinner is a set of loading spinners for Dear ImGui, the immediate mode GUI library. It is header-only and written in C++, so there is nothing to build, nothing to link and no dependency to resolve. You add a header to your project and call the spinner you want.

The audience is narrow and well defined: anyone building a desktop or tool UI on Dear ImGui who needs a progress indicator that looks finished rather than a hand-rolled animated triangle. Every spinner draws itself with the ImGui drawing primitives, so a spinner inherits the same style, clipping and colour handling as the rest of the interface, and it sits inside a window like any other element.

That last point is the reason the library exists in this shape. A spinner is not a separate widget with its own rendering model, it is a function that draws into the current window. That is why the usage example places the call inside an ImGui window and why the colour is passed as an `ImColor` rather than configured through a style entry.

The catalogue is large and, importantly, subdivided. Bars, dots, text loaders, shapes and the interactive demo each live in their own file, and the README is explicit that each file includes the one below it, so you include only the highest level header you need. That structure is the project's main engineering decision, and it cuts both ways.

Include only the top header you actually need

The header table is short and worth reading before anything else. `imspinner.h` holds the spinners themselves and nothing else. `imspinner_bars.h` adds the bar chart spinners such as `SpinnerFadeBars` and includes `imspinner.h`. `imspinner_dots.h` adds dot based spinners such as `SpinnerBounceDots`, and `imspinner_text.h` adds text loaders such as `SpinnerTextFade`, both including `imspinner.h`. `imspinner_shapes.h` adds shape spinners such as `SpinnerMorphShape`.

The two remaining headers are the ones that change how you write your code. `imspinner_compat.h` provides a `Spinner<>` typed dispatcher and includes `imspinner.h` plus `imspinner_bars.h`. `imspinner_demo.h` provides the interactive demo gallery, `demoSpinners()`, and includes everything above together with the compat header.

So there are two usage styles. Call the named spinner functions directly, which means including one family header, or go through the `Spinner<>` dispatcher, which ties a spinner type to a name and switches on it, which means pulling in the compat header and the bar spinners with it. The docs mention that `SpinnerBarChartSine` is wired into the core dispatcher as `Spinner<e_st_barchartsine>`, so the dispatcher exposes an enumeration of spinner types rather than being a generic callback.

The trade-off in this layering is compile time. Choosing the compat header for the dispatcher pulls in the bar spinners whether or not you use them, and the demo header pulls in everything. For a large project where a spinner is only needed in one screen, the fine grained headers are the sensible choice.

Drawing a spinner is one call with a label, size and colour

The call signature is uniform across the library. A spinner takes a name, a size, a colour and, depending on the family, one or two tuning floats plus an integer mode. The example in the project documentation shows the shortest form:

cpp
#include "../imspinner/imspinner.h"          // graphical spinners only
// or
#include "../imspinner/imspinner_text.h"     // + text loaders
// or
#include "../imspinner/imspinner_demo.h"     // + interactive demo

// use a single spinner anywhere inside an ImGui window:
ImSpinner::SpinnerRainbow("rainbow", 16.f, 2.f, ImColor(255, 255, 255), 8.f);

The bar family shows the same shape with the extra parameters in place:

cpp
#include "../imspinner/imspinner_bars.h"   // pulls in imspinner.h
...
ImSpinner::SpinnerFadeBars("bars", 6.f, ImColor(255, 255, 255), 2.8f, 3);
ImSpinner::SpinnerBarChartRainbow("rainbow", 16.f, 4.f, ImColor(255, 255, 255), 4.f);

Every spinner lives in the `ImSpinner` namespace, so there is no chance of colliding with a name in your own code. The first argument is a string label, which doubles as the identifier used by the dispatcher and by the demo gallery, and the remaining arguments are the size, the colour, a couple of animation parameters and a mode number.

The size is expressed as a float and the colour as an `ImColor`, so a spinner scales with the same units as the rest of your interface and picks up a palette change without special handling. That is a small thing, but it is the difference between a spinner that belongs in the design and one that looks pasted on.

The demo header is also the test harness

Testing the library means including the demo header and calling one function per frame. There is no define to set and no build flag to flip: including `imspinner_demo.h` is the opt-in itself, which is stated plainly in the how to test section.

cpp
#include "../imspinner/imspinner_demo.h"

int main(int, char**) {
  ...
  while (!done) {
     ...
     ImSpinner::demoSpinners();
  }
}

`demoSpinners()` renders an interactive gallery, and the documentation describes how to drive it: enable edit mode with a checkbox labelled 'show number', or experiment with the options. The 'show number' control displays the numeric parameter you are adjusting, which turns the gallery into a tuning tool rather than a static list.

That gallery is also the fastest way to see the whole catalogue, because the bar section alone lists several dozen named effects. The bar table runs from `SpinnerFadeBars`, where vertical bars fade in sequence, through `SpinnerBarsConicWalk`, where two conic corners step along a 2x2 path, to `SpinnerBarsSlot`, where a dot passes through two opening bars while the figure rotates. The dot, text and shape headers follow the same pattern of naming and description, with each entry saying in a few words what the animation does.

For a developer choosing between them, the demo is worth more than the table, since the effects are subtle and a static description rarely distinguishes a fade from a stagger.

Modes change timing, not appearance

Every spinner takes a mode number, and the mode table defines three values rather than an open range. Mode `0` is the default timing and direction. Mode `1` is an alternate animation for that spinner, and the table lists the kinds of alternation involved: a sync pulse instead of a stagger, a reversed stagger, a top anchor instead of a bottom one, a single walking tile, synchronised rows, or a reverse grid wave. Mode `2` reverses the timeline, expressed in the documentation as the transformation `t` to `1` minus `t`.

This is a good design for a library that wants to offer variety without multiplying the function count. The same `SpinnerFadeBars` call with mode `1` looks different enough to use in a second place, and mode `2` gives you a reversed animation for a spinner that already exists, which is useful when a progress indicator needs to feel like it is winding down.

It also means the parameter list is not self evident. The mode value is a plain integer passed at the call site, so the only way to know what mode `1` does for a given spinner is to try it in the demo gallery, where the numbers can be toggled. The documentation does not map each mode to each spinner, which is the main gap in the reference documentation.

A copied header set, not a packaged dependency

The integration story is the weakest part of the project, and it is worth being explicit about. The repository root holds the headers directly, `imspinner.h`, `imspinner_bars.h`, `imspinner_compat.h`, `imspinner_demo.h`, `imspinner_dots.h`, `imspinner_shapes.h` and `imspinner_text.h`, together with a `LICENSE.txt`, a `README.md` and a `cimspinner/` directory. There is no CMake project file, no package manifest, no version tag and no published release, so adopting the library means copying files into your source tree and updating the copy by hand.

The include paths in the examples confirm the expectation, since they are written as paths relative to a sibling directory, such as `../imspinner/imspinner.h`. That is the shape of a vendored dependency, and it means your copy will not receive fixes unless you remember to re-copy them.

The `cimspinner/` directory is listed in the repository but its purpose is not described anywhere in the documentation, so treat it as an undocumented extra rather than a supported entry point. The rest of the documentation is similarly silent on how the library is expected to be distributed, whether it works with a package manager, and what threading assumptions it makes.

Two practical consequences follow. First, if your build already depends on Dear ImGui, adding imspinner costs a few kilobytes of header text and no binary. Second, if you need a dependency you can version, `git subtree` or a submodule is more realistic than a package manager entry. The licence is MIT, which is permissive enough for that arrangement, and since the repository publishes no releases you track the default branch instead, where the last push was on 2026-10-12.

Editorial conclusion

imspinner suits Dear ImGui developers who want a polished loading indicator without writing their own draw calls, and who are happy to copy a handful of header files into a project. It does not suit a build that wants a packaged dependency, since the repository carries no build files or package manifest and the include paths in the examples assume the headers sit next to your sources, and it does not suit a project without Dear ImGui, which it does not vendor. Before adopting, read imspinner_compat.h and imspinner_demo.h for the dispatcher and the demo gallery, and check the MIT terms in LICENSE.txt, since the repository publishes no releases and the last push was on 2026-10-12.

Frequently asked questions

How do I add a spinner to a Dear ImGui window?

Include the header for the family you want and call the spinner inside your window code, for example `ImSpinner::SpinnerRainbow("rainbow", 16.f, 2.f, ImColor(255, 255, 255), 8.f);`. Each spinner takes a label, a size, a colour and animation parameters, and draws itself with the ImGui drawing primitives.

Which imspinner header should I include?

Include only the highest level header you need: `imspinner.h` for the spinners themselves, `imspinner_bars.h`, `imspinner_dots.h`, `imspinner_text.h` or `imspinner_shapes.h` for one family, `imspinner_compat.h` for the `Spinner<>` dispatcher, and `imspinner_demo.h` for the interactive gallery.

How do I preview and tune the imspinner animations?

Include `imspinner_demo.h`, which is the opt-in by itself, and call `ImSpinner::demoSpinners()` once per frame. The gallery has an edit mode with a 'show number' checkbox and options for changing the animation parameters.

What do the spinner mode numbers 0, 1 and 2 do?

Mode 0 is the default timing and direction, mode 1 is an alternate animation for that spinner such as a sync pulse or reversed stagger, and mode 2 reverses the timeline so the animation runs as `t` to `1` minus `t`.

Is imspinner available as a package or library manager dependency?

No. The repository ships the header files directly, has no build files or package manifest, and publishes no GitHub releases, so the library is copied into a project as vendored source. The licence is MIT and the last push was on 2026-10-12.

Official sources

  1. dalerank/imspinner on GitHub
  2. Issues
  3. License: MIT
  4. README
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/dalerank-imspinner.svg)](https://hysenlabs.com/projects/dalerank-imspinner)

Was this useful?