nspin-esm is a lightweight and efficient Node.js spinner package built entirely with native features for optimal performance. This is an ESM-only package, designed specifically for modern Node.js environments (v22+). It provides a simple, intuitive, and dependency-free API for creating and managing spinner animations in your applications.
- nspin-esm
-
ESM-Only & Modern: nspin-esm is built as an ESM-only package, taking full advantage of modern Node.js features (e.g.,
styleText
fromnode:util
,performance.now()
, and advanced console manipulation) for 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-esm is completely dependency-free, ensuring a lightweight installation and enhanced security. -
Clean & Modular API: Following SOLID principles, nspin-esm 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.
nspin-esm 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.
-
ESM-Only: Designed exclusively as an ECMAScript Module package, ensuring modern module resolution and a cleaner development experience.
-
Native Styling: Leverages the modern
styleText
API for styling spinner frames, eliminating manual ANSI codes. -
Chainable API: Methods like
start
,updateText
,updateFrames
, 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.
-
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.
Install nspin-esm via npm:
npm install nspin-esm
Below are several examples demonstrating the functionality of nspin-esm.
A basic example that shows how to initialize and run a spinner.
import { Spinner } from "nspin-esm";
// 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-esm";
// 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-esm";
// Moon Phases Spinner
export 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-esm";
// 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-esm";
// 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 demonstrates how nspin-esm degrades gracefully when running in a non-TTY environment.
import { Spinner } from "nspin-esm";
// 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. -
stop(finalText?: string): this
Stops the spinner and displays the final message.
For detailed type definitions, please refer to SpinnerOptions and FormatOptions.
nspin-esm is built using standard Node.js tools and optimized for performance. Key commands include:
-
Build:
npm run build
-
Prepublish:
TheprepublishOnly
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-esm, 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.