nspin is a lightweight and efficient Node.js spinner package built entirely with native features for optimal performance. Designed with modern Node.js (v22+) in mind, nspin provides a simple, intuitive, and dependency-free API for creating and managing spinner animations in your applications.
- nspin
- Overview
- Index
- Why Choose nspin?
- Requirements
- Features
- Installation
- Usage Examples
- Example 1: Simple Spinner Initialization
- Example 2: Spinner with Dynamic Message Updates
- Example 3: Concurrent Spinners
- Example 4: Dynamic Update of Spinner Frames
- Example 5: Configuring Spinner Position
- Example 6: Using Pause/Resume, Interval Updates, and State Inspection
- Example 7: Degraded Output in Non-TTY Environments
- API Reference
- Build & Publication
- Development
- Support
- Feedback
- Contributing
- Code of Conduct
- Changelog
- License
-
Modern & Native: Built using the latest Node.js APIs (e.g.,
styleText
fromnode:util
,performance.now()
, and advanced console manipulation), nspin ensures high performance and reliability. -
Requires Node.js 22+: Leveraging Node.js v22+ features guarantees full compatibility with the most modern versions of Node.js, reducing external dependencies and the overall footprint.
-
Zero Dependencies: Unlike many spinner libraries that rely on external packages (like
chalk
orora
), nspin is completely dependency-free, ensuring a lightweight installation and enhanced security. -
Clean & Modular API: Following SOLID principles, nspin offers a chainable API that simplifies spinner management and supports multiple concurrent spinners.
-
Adaptive Output: Automatically adjusts for both TTY and non-TTY environments, ensuring clear output regardless of the terminal's capabilities.
-
Dynamic Update of Frames: Change the spinner animation frames on the fly using the
updateFrames(newFrames: string[])
method. -
Position Configuration: Configure the spinner to appear either on the left (default) or right of the text via the
position
option. -
Enhanced Control & Extensibility: With new methods like
pause()
,resume()
, andrestart()
, along with state inspection methods (getCurrentFrame()
,getElapsedTime()
, andgetTimerId()
), you can control the animation in real time, facilitate smooth transitions, and build robust extensions (like an ExtendedSpinner) without depender de soluciones internas o hacks.
nspin requires Node.js version 22 or higher. This requirement ensures access to modern features such as:
styleText
fromnode:util
for elegant text styling without manual ANSI escape codes.performance.now()
for high-resolution timing.- Native console methods for precise cursor control.
-
Lightweight & Efficient: Uses native Node.js features to achieve high performance with minimal overhead.
-
Native Styling: Leverages the modern
styleText
API for styling spinner frames, eliminating manual ANSI codes. -
Chainable API: Methods like
start
,updateText
,updateFrames
,pause
,resume
,restart
,setInterval
, andstop
return the spinner instance for fluent usage. -
Multiple Spinner Support: Easily manage several concurrent spinners without interference.
-
Modular & Extensible: Designed following SOLID principles for clean, maintainable, and extendable code. The internal state is exposed via dedicated getters to support extensions like ExtendedSpinner.
-
Dynamic Update of Frames: Change the spinner animation frames on the fly using
updateFrames(newFrames: string[])
. -
Position Configuration: Choose whether the spinner appears to the left or right of the message via the
position
option. -
Enhanced Control: Use
pause()
to stop the spinner temporarily andresume()
to continue the animation. Adjust the update interval dynamically withsetInterval(newInterval: number)
and inspect it withgetInterval()
. -
State Inspection: Access the internal state through:
getCurrentFrame()
: Returns the current frame index.getElapsedTime()
: Returns the elapsed time in milliseconds.getTimerId()
: Returns the current timer identifier.
-
Restart Capability: The
restart()
method allows you to stop and restart the spinner without perder la configuración actual.
Install nspin via npm:
npm install nspin
Below are several examples demonstrating the functionality of nspin.
A basic example that shows how to initialize and run a spinner.
import { Spinner } from "nspin";
// Simple Rotation spinner frames
const simpleRotation = ["|", "/", "-", "\\"];
const spinner = new Spinner({
frames: simpleRotation,
interval: 100
}).start("Loading...");
setTimeout(() => {
spinner.stop("Done!");
}, 3000);
This example demonstrates how to update the spinner's message in real time.
import { Spinner } from "nspin";
// Blinking Dot spinner frames
const blinkingDot = [" ", ". ", ".. ", "...", " ..", " ."];
const spinner = new Spinner({
frames: blinkingDot,
interval: 120,
format: "green"
}).start("Initializing...");
let progress = 0;
const interval = setInterval(() => {
progress += 10;
spinner.updateText(`Progress: ${progress}%`);
if (progress >= 100) {
clearInterval(interval);
spinner.stop("Task complete!");
}
}, 500);
This example shows how to run multiple spinners at the same time to simulate parallel tasks.
import { Spinner } from "nspin";
// Moon Phases Spinner
const moonPhasesSpinner = ["◐", "◓", "◑", "◒"];
const spinner1 = new Spinner({
frames: moonPhasesSpinner,
interval: 100,
format: "blue"
}).start("Task 1: Downloading...");
// Parentheses Rotation spinner frames
const parenthesesRotation = ["(-)", "(\\)", "(|)", "(/)"];
const spinner2 = new Spinner({
frames: parenthesesRotation,
interval: 120,
format: "magenta"
}).start("Task 2: Processing...");
setTimeout(() => {
spinner1.stop("Task 1 complete!");
}, 4000);
setTimeout(() => {
spinner2.stop("Task 2 complete!");
}, 5000);
In this example, we demonstrate how to change the spinner frames dynamically during runtime.
import { Spinner } from "nspin";
// Bouncing Ball spinner frames
const bouncingBall = [
"(o )",
"( o )",
"( o )",
"( o )",
"( o)",
"( o )",
"( o )",
"( o )"
];
// Rotating Dot Spinner frames
const rotatingDotSpinner = [".", "o", "O", "o"];
const spinner = new Spinner({
frames: bouncingBall,
interval: 100
}).start("Task in progress...");
// Update spinner frames after 5 seconds
setTimeout(() => {
spinner.updateFrames(rotatingDotSpinner);
spinner.updateText("Now using a different spinner...");
}, 5000);
// Stop spinner after 10 seconds
setTimeout(() => spinner.stop("Done!"), 10000);
This example shows how to configure the spinner's position relative to the text.
import { Spinner } from "nspin";
// Progress Bar spinner frames
const progressBar = [
"[ ]",
"[= ]",
"[== ]",
"[=== ]",
"[====]",
"[ ===]",
"[ ==]",
"[ =]"
];
// Spinner with left alignment (default)
const spinnerLeft = new Spinner({
frames: progressBar,
interval: 100,
position: 'left'
}).start("Left aligned spinner");
// Spinner with right alignment
const spinnerRight = new Spinner({
frames: progressBar,
interval: 100,
position: 'right'
}).start("Right aligned spinner");
// Stop both spinners after 8 seconds
setTimeout(() => {
spinnerLeft.stop("Left spinner done");
spinnerRight.stop("Right spinner done");
}, 8000);
This example shows how to use the new pause()
, resume()
, setInterval()
, and state inspection methods to control the spinner animation dynamically.
import { Spinner } from "nspin";
const spinner = new Spinner({
frames: ["|", "/", "-", "\\"],
interval: 100
}).start("Processing...");
// Pause the spinner after 2 seconds
setTimeout(() => {
spinner.pause();
console.log("Spinner paused.");
console.log(`Current Frame: ${spinner.getCurrentFrame()}`);
}, 2000);
// Resume the spinner after 4 seconds
setTimeout(() => {
spinner.resume();
console.log("Spinner resumed.");
}, 4000);
// Update the spinner interval after 6 seconds
setTimeout(() => {
spinner.setInterval(50);
console.log(`New interval: ${spinner.getInterval()}ms`);
}, 6000);
// Restart the spinner after 7 seconds (without losing configuration)
setTimeout(() => {
spinner.restart();
console.log("Spinner restarted.");
}, 7000);
// Stop the spinner after 8 seconds
setTimeout(() => spinner.stop("Process complete!"), 8000);
This example demonstrates how nspin degrades gracefully when running in a non-TTY environment.
import { Spinner } from "nspin";
// Crosshair Spinner
const crosshairSpinner = [
"[+]",
"[x]",
"[-]",
"[x]"
];
// Simulate non-TTY mode for demonstration (in practice, this is determined by process.stdout.isTTY)
if (!process.stdout.isTTY) {
console.log("Non-TTY mode active.");
}
const spinner = new Spinner({
frames: crosshairSpinner,
interval: 100,
format: "yellow"
}).start("Running in non-TTY mode...");
setTimeout(() => {
spinner.stop("Finished in non-TTY mode.");
}, 3000);
-
new Spinner(options: SpinnerOptions): Spinner
Creates a new spinner instance.Options:
frames
: An array of spinner frames (e.g.,["-", "\\", "|", "/"]
).interval
(optional): Time between frames in milliseconds (default is 80).format
(optional): Format options for styling the spinner (passed tostyleText
).position
(optional): Position of the spinner relative to the text. Accepted values are'left'
(default) or'right'
.
-
start(text?: string): this
Starts the spinner with an optional initial message. -
updateText(newText: string): this
Updates the spinner's message in real time. -
updateFrames(newFrames: string[]): this
Dynamically updates the spinner frames and resets the frame counter. -
pause(): this
Temporarily pauses the spinner animation without resetting its state. -
resume(): this
Resumes the spinner animation if it was paused. -
restart(): this
Stops and restarts the spinner using the current configuration, preserving its state. -
getCurrentFrame(): number
Returns the current frame index of the spinner. -
getInterval(): number
Returns the current interval (in milliseconds) of the spinner. -
setInterval(newInterval: number): this
Sets a new interval for the spinner and resets the timer if active. -
getElapsedTime(): number
Returns the elapsed time in milliseconds since the spinner started. -
getTimerId(): ReturnType<typeof setInterval> | null
Returns the current timer identifier or null if no timer is active. -
stop(finalText?: string): this
Stops the spinner and displays the final message.
For detailed type definitions, please refer to SpinnerOptions and FormatOptions.
nspin is built using standard Node.js tools and optimized for performance. Key commands include:
-
Build:
npm run build
-
Prepublish: The
prepublishOnly
script ensures a production build is generated and compressed before publishing:npm run prepublishOnly
For development, use your preferred Node.js environment along with the provided build and test scripts. Recommended commands include:
- Build:
npm run build
- Test:
npm run test
- Run:
npm start
If you encounter any issues or have suggestions for improvements, please open an issue on GitHub.
If you enjoy using nspin, please consider leaving a review on GitHub or sharing your feedback.
Contributions are welcome! To contribute:
- Fork the repository.
- Create your feature branch (
git checkout -b feature/my-new-feature
). - Commit your changes (
git commit -am 'Add some feature'
). - Push to the branch (
git push origin feature/my-new-feature
). - Open a pull request.
Please refer to our Contributing Guidelines for more details.
We strive to create a welcoming, inclusive, and respectful community. Please review our Code of Conduct before contributing.
For a complete list of changes, see the CHANGELOG.md.
This package is licensed under the MIT License.