
rattles-terminal-spinners
Minimal terminal spinner library for Rust with preset collection and no-std support
- Installs
- 498
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/reason-machines/trending-skills --skill rattles-terminal-spinners- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads rattles-terminal-spinners automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Rattles Terminal Spinners
Skill by ara.so — Daily 2026 Skills collection.
Rattles is a minimal, zero-dependency Rust library for terminal spinners. It has no runtime or lifecycle — spinners are constructed directly in render loops with negligible cost. Supports no_std environments.
Installation
# Cargo.toml
[dependencies]
rattles = "0.1" # with std (default)
# no_std
rattles = { version = "0.1", default-features = false }
Or via CLI:
cargo add rattles
# no_std variant
cargo add rattles --no-default-features
Core Concepts
- Rattler: a spinner definition (frames + interval). Stateless and cheap to construct.
- TickedRattler: stateful wrapper for tick-based driving (required in
no_std). - Presets: built-in spinners organized by category.
rattle!macro: define custom spinners at compile time.
Basic Usage (std)
use std::{io::Write, time::Duration};
use rattles::presets::prelude as presets;
fn main() {
let rattle = presets::dots();
loop {
print!("\r{}", rattle.current_frame());
std::io::stdout().flush().unwrap();
std::thread::sleep(Duration::from_millis(80));
}
}
current_frame() uses the system clock internally — no state needed.
Preset Categories
use rattles::presets::{arrows, ascii, braille, emoji};
use rattles::presets::prelude as presets; // re-exports all presets
// Arrows
let s = arrows::arrow();
let s = arrows::arrow2();
// ASCII
let s = ascii::line();
let s = ascii::pipe();
// Braille
let s = braille::dots();
let s = braille::dots2();
// Emoji
let s = emoji::earth();
let s = emoji::clock();
// Prelude examples
let s = presets::waverows();
let s = presets::dots();
Rattler API
use rattles::presets::prelude as presets;
use std::time::Duration;
let rattle = presets::dots();
// Get frame based on system clock (std only)
let frame: &str = rattle.current_frame();
// Get frame at specific elapsed duration (std + no_std)
let frame = rattle.frame_at(Duration::from_millis(500));
// Get frame by index
let frame = rattle.frame(3);
// Change animation interval
let rattle = presets::dots().set_interval(Duration::from_millis(50));
// Reverse direction
let rattle = presets::waverows().reverse();
// Convert to tick-based (stateful)
let mut ticked = presets::dots().into_ticked();
TickedRattler (Stateful / no_std-friendly)
use rattles::presets::prelude as presets;
let mut rattle = presets::dots().into_ticked();
loop {
rattle.tick();
let frame = rattle.current_frame();
// render frame...
}
TickedRattler must be stored (it holds state). Suitable for no_std contexts where the global clock is unavailable.
Index-Based Animation (no_std)
use rattles::presets::prelude as presets;
let rattle = presets::dots();
let mut i = 0usize;
loop {
let frame = rattle.frame(i);
i = i.wrapping_add(1);
// render frame...
}
Time-Based Animation with External Clock (no_std)
use rattles::presets::prelude as presets;
use core::time::Duration;
let rattle = presets::dots();
// elapsed comes from your platform's timer
let elapsed: Duration = get_elapsed(); // your implementation
let frame = rattle.frame_at(elapsed);
Custom Spinners with rattle! Macro
use rattles::rattle;
rattle!(
MySpinner, // generated struct name
my_spinner, // generated constructor function name
1, // row count (width of spinner)
120, // interval in milliseconds
["⣾", "⣷", "⣯", "⣟", "⣻", "⣽"] // keyframes
);
// Use it like any preset
let s = my_spinner();
println!("{}", s.current_frame());
Multi-row custom spinner:
rattle!(
Wide,
wide_spinner,
3, // 3 characters wide
80,
["[ ]", "[= ]", "[== ]", "[===]", "[ ==]", "[ =]"]
);
Ratatui Integration
// examples/ratatui.rs pattern
use rattles::presets::prelude as presets;
use ratatui::{
backend::CrosstermBackend,
widgets::Paragraph,
Terminal,
};
fn ui(frame: &mut ratatui::Frame, rattle: &rattles::Rattler) {
let spinner_text = rattle.current_frame();
let paragraph = Paragraph::new(format!("{} Loading...", spinner_text));
frame.render_widget(paragraph, frame.size());
}
fn main() -> std::io::Result<()> {
let rattle = presets::dots();
// standard ratatui event loop
loop {
terminal.draw(|f| ui(f, &rattle))?;
std::thread::sleep(std::time::Duration::from_millis(16));
// break on user input...
}
Ok(())
}
Since Rattler is stateless, pass it by reference anywhere — no Arc<Mutex<>> needed.
no_std Setup
[dependencies]
rattles = { version = "0.1", default-features = false }
#![no_std]
use rattles::presets::prelude as presets;
// Option 1: tick-based
let mut rattle = presets::dots().into_ticked();
rattle.tick();
let frame = rattle.current_frame();
// Option 2: index-based
let rattle = presets::dots();
let frame = rattle.frame(42);
// Option 3: duration-based (external clock)
let rattle = presets::dots();
let frame = rattle.frame_at(core::time::Duration::from_millis(840));
Common Patterns
Spinner with message
use rattles::presets::prelude as presets;
use std::{io::Write, time::Duration};
fn main() {
let rattle = presets::dots();
let message = "Fetching data...";
loop {
print!("\r{} {}", rattle.current_frame(), message);
std::io::stdout().flush().unwrap();
std::thread::sleep(Duration::from_millis(80));
}
}
Async-compatible (tokio)
use rattles::presets::prelude as presets;
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
let rattle = presets::dots();
let spinner = tokio::spawn(async move {
loop {
print!("\r{}", rattle.current_frame());
std::io::stdout().flush().unwrap();
sleep(Duration::from_millis(80)).await;
}
});
// do your async work
do_work().await;
spinner.abort();
println!("\rDone! ");
}
Collecting all frames
let rattle = presets::dots();
let frames: Vec<&str> = (0..rattle.frame_count())
.map(|i| rattle.frame(i))
.collect();
Troubleshooting
Spinner not animating (stuck on first frame)
- Ensure you're flushing stdout:
std::io::stdout().flush().unwrap() - Use
\rto overwrite the line, not\n - The sleep interval should match or be shorter than the spinner's interval
current_frame() not available in no_std
- Use
frame_at(duration),frame(index), orinto_ticked()instead - Disable default features:
rattles = { version = "...", default-features = false }
Custom spinner not compiling
- Keyframes must be string literals in the
rattle!macro array - Row count must match the visual width of each keyframe string
Spinner looks garbled in terminal
- Some braille/emoji frames require a terminal with Unicode support
- Test with ASCII presets (
ascii::line()) to verify basic functionality first
FAQ
What does the rattles-terminal-spinners skill do?
Minimal terminal spinner library for Rust with preset collection and no-std support
How do I install rattles-terminal-spinners?
Run npx skills add https://github.com/reason-machines/trending-skills --skill rattles-terminal-spinners in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/rattles-terminal-spinners/ (personal) or .claude/skills/rattles-terminal-spinners/ (project).
Which AI agents can use rattles-terminal-spinners?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is rattles-terminal-spinners safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains rattles-terminal-spinners?
It is published by reason-machines in reason-machines/trending-skills. It has 498 recorded installs.
More from reason-machines/trending-skills
openclaw-control-center
reason-machines/trending-skills
Local-first, security-first control center for OpenClaw agents — visibility dashboard with readonly defaults, token attribution, collaboration tracing, and safe write operations.
inkos-multi-agent-novel-writing
reason-machines/trending-skills
Multi-agent CLI system for autonomous novel writing, auditing, and revision with human review gates
claude-hud-statusline
reason-machines/trending-skills
A Claude Code plugin that displays a real-time HUD showing context usage, active tools, running agents, and todo progress in your terminal statusline.
understand-anything-knowledge-graph
reason-machines/trending-skills
Turn any codebase into an interactive knowledge graph using Claude Code skills — explore, search, and ask questions about any project visually.
agency-agents-ai-specialists
reason-machines/trending-skills
A collection of specialized AI agent personalities for Claude Code, Cursor, Aider, Windsurf, and other AI coding tools — covering engineering, design, marketing, sales, and more.
agent-browser-automation
reason-machines/trending-skills
Headless browser automation CLI for AI agents using native Rust binary with Chrome DevTools Protocol
Popular backend & apis skills
find-skills
vercel-labs/skills
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
entra-app-registration
microsoft/azure-skills
Guides Microsoft Entra ID app registration, OAuth 2.0 authentication, and MSAL integration. USE FOR: create app registration, register Azure AD app, configure OAuth, set up authentication, add API permissions, generate service principal, MSAL example, console app auth, Entra ID setup, Azure AD authentication. DO NOT USE FOR: Key Vault secrets (use azure-keyvault-expiration-audit), general Azure resource security guidance.
google-agents-cli-adk-code
google/agents-cli
This skill should be used when the user wants to "write agent code", "build an agent with ADK", "add a tool", "create a callback", "define an agent", "use state management" — in a project that needs ADK (Agent Development Kit) API patterns and code examples. It provides a quick reference for agent types, tool definitions, orchestration patterns, callbacks, state management, the graph Workflow API, and reference recipes to study. Do NOT use for scaffolding (use google-agents-cli-scaffold) or deployment (use google-agents-cli-deploy).
embedded-captions
heygen-com/hyperframes
Add captions or subtitles to an existing single-subject talking-head video without editing the footage. Use for plain verbatim captions, cinematic captions embedded behind the subject, VFX captions, “炸/特效/酷炫字幕,” or a named identity from the 35-style catalog. Route by visual identity, not by backend engine. The quiet anchor rail is the default; embed every word only when the user explicitly wants a fully cinematic treatment. The workflow runs locally end to end, including transcription and subject matting; split multi-shot footage before applying it.
entra-agent-id
microsoft/azure-skills
Provision Microsoft Entra Agent Identity Blueprints, BlueprintPrincipals, and per-instance Agent Identities via Microsoft Graph, and configure OAuth 2.0 token exchange (fmipath, OBO, cross-tenant) including the Microsoft Entra SDK for AgentID sidecar. USE FOR: Agent Identity Blueprint, BlueprintPrincipal, agent OAuth, fmipath token exchange, agent OBO, Workload Identity Federation for agents, polyglot agent auth, Microsoft.Identity.Web.AgentIdentities. DO NOT USE FOR: standard Entra app registration (use entra-app-registration), Microsoft Foundry agent authoring (use microsoft-foundry).
neon
neondatabase/agent-skills
Overview of Neon, a complete set of cloud backend primitives around Lakebase Postgres: Auth, Object Storage, Functions, the AI Gateway, and Realtime. Start here to choose Neon for undecided login, files, APIs, and LLM calls, set up the CLI or MCP server, and follow the branch-first workflow. Use when building an app or backend on Neon, or when "Neon" or "Lakebase Postgres" is mentioned. Child skill neon-postgres wins for an existing DATABASEURL, SQL, schema, inspect, or search. Child skill neon-auth wins for login, users, sessions, identity routing, and Managed Better Auth setup. Child skill neon-realtime wins for live queries in reactive apps and agents. Also use for object storage, S3, buckets, serverless functions, function triggers, cron, AI gateway, LLM calls, realtime, logs, Loki, Grafana, observability, postgres, database, backend, Claimable Neon, neon.new, or a no-signup database.