tui-shimmer: How a Terminal Learns to Shimmer
A tiny Rust library turns loading text into a moving highlight, with a cosine curve, true-color blending, and a fallback path for older terminals.

Demo usage from my VT Code coding agent.
- tui-shimmer proves that terminal polish can be expressive without pretending the terminal is a browser.
- Its real trick is a compact rendering pipeline that turns elapsed time into phase, phase into intensity, and intensity into style.
- The crate treats terminal fragmentation as a first-class constraint, so the effect still degrades gracefully when true color is unavailable.
- What looks like a small cosmetic crate is actually a strong argument that TUIs have entered a more design-conscious era.
A loading state in a terminal usually does one job: it tells you to wait. tui-shimmer does the same job, but it gives the pause a pulse. That sounds cosmetic until you realize how much trust and clarity live inside a loading animation, especially in a tool that people use all day.
The terminal, but less terminal
Most TUI loading states are functional and forgettable. Spinners spin, progress bars fill, and static placeholders hold space. `tui-shimmer` borrows the emotional signal of web shimmer, then translates it into terminal terms: spans, colors, character positions, and a very small performance budget.
What Vinh Nguyen is really shipping
The crate is maintained by Vinh Nguyen, who also uses the effect in his VT Code agent. That matters because it suggests this is not a novelty extract from a demo reel. It reads like utility that escaped from a real product path and got cleaned up for other Ratatui users.
How the shimmer is actually built
The implementation is small, but it is not casual. The library takes elapsed time, folds it into a looping phase, turns that phase into a moving center point, then computes character-level intensity around that center. From there it chooses either smooth RGB blending or a discrete ANSI fallback, depending on what the terminal can really do.
let phase = (elapsed.as_secs_f32() / SHIMMER_SWEEP_SECONDS).rem_euclid(1.0);
let distance = (character_index as f32 - shimmer_center(phase)).abs();
let intensity = intensity_lut(distance);
let style = if supports_true_color() {
blend_rgb(base_color, Color::White, intensity)
} else {
ansi_gray_bucket(intensity)
};
append_span_or_merge(text_chunk, style);
Two details make the implementation feel mature. First, the cosine-based look-up table avoids a harsh linear sweep, so the shimmer reads as a soft band rather than a blinking stripe. Second, adjacent characters with the same style are merged into spans, which keeps the rendering path lean instead of spraying the terminal with tiny objects.
Why the fallback path matters
This is where `tui-shimmer` earns its credibility. It checks the environment, looks for true color support, and still produces a sensible result when the terminal is older or more constrained. That is the real product decision here. A pretty animation that breaks on half the terminals in the wild is not polish, it is fragility.
Compared with the usual loading states
| Pattern | What it signals | Strength | Weakness | Best fit |
|---|---|---|---|---|
| Spinner | Work is ongoing | Tiny, universal, cheap | Says nothing about structure or duration | Short waits and background tasks |
| Progress bar | A task has measurable completion | Great when the finish line is real | Misleading when the endpoint is fuzzy | Known-duration jobs |
| Static skeleton | Content will arrive here | Sets layout expectations | Feels frozen rather than alive | Feed and panel placeholders |
| tui-shimmer | Wait, but with rhythm and polish | Adds motion without leaving the terminal | Depends on color capability for its best look | Indeterminate loads in modern TUIs |
The comparison is not about feature parity. It is about information quality. A spinner says the system is busy. A shimmer says the UI is alive, the content matters, and the wait itself has been designed.
What this says about TUIs now
`tui-shimmer` is small enough to miss if you only scan for headline features. That would be a mistake. It shows that terminal interfaces are moving past mere utility, toward motion, nuance, and brand texture, while still respecting the terminal as a constrained medium. In other words, polish is no longer a contradiction in TUI design.





