ora vs chalk
Command Line Interface (CLI) Enhancements
orachalkSimilar Packages:

Command Line Interface (CLI) Enhancements

chalk and ora are popular npm packages used to enhance the command line interface (CLI) experience for users and developers. chalk is a library for styling terminal output with colors, backgrounds, and text formatting, making it easier to highlight important information, errors, or warnings in console applications. It provides a simple and intuitive API for adding color to text, which can improve the readability and visual appeal of command line outputs. On the other hand, ora is a package designed for creating elegant loading spinners in the terminal. It allows developers to indicate that a process is ongoing, which can be particularly useful for long-running tasks, providing users with visual feedback that something is happening. ora supports customizable spinner styles and messages, helping to enhance the user experience in CLI applications by making them feel more interactive and responsive.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
ora62,538,8719,62738.1 kB0a month agoMIT
chalk023,04044.3 kB56 months agoMIT

Feature Comparison: ora vs chalk

Purpose

  • ora:

    ora is focused on indicating progress. It provides a simple way to create spinners in the terminal, which are animated indicators that show a process is ongoing. This is especially useful for long-running tasks.

  • chalk:

    chalk is focused on styling text in the terminal. It allows you to add colors, backgrounds, and styles (like bold, italic, underline) to your console output, making it more visually appealing and easier to read.

Customization

  • ora:

    ora allows customization of spinner styles, colors, and messages. You can choose from different spinner animations and even create your own. This makes it more flexible for indicating different types of progress.

  • chalk:

    chalk offers extensive customization for text styling. You can easily combine multiple styles and create reusable style functions. However, the customization is primarily around colors and text styles.

Ease of Use

  • ora:

    ora is also easy to use, with a simple API for starting and stopping spinners. It requires minimal setup and is intuitive, making it quick to implement in CLI applications.

  • chalk:

    chalk has a straightforward API that makes it easy to use. Adding color to text is as simple as calling a function. It is well-documented and easy to integrate into any project.

Performance

  • ora:

    ora is designed to be efficient, but the performance can vary depending on the complexity and duration of the spinners. For most use cases, the impact is negligible.

  • chalk:

    chalk is lightweight and has minimal impact on performance. Styling text does not add significant overhead, making it suitable for applications where performance is a concern.

Code Example

  • ora:

    Here is an example of using ora to create a loading spinner:

    const ora = require('ora');
    
    const spinner = ora('Loading...').start();
    
    setTimeout(() => {
      spinner.succeed('Done!');
    }, 3000);
    
  • chalk:

    Here is a simple example of using chalk to style terminal output:

    const chalk = require('chalk');
    
    console.log(chalk.blue('This is a blue message!'));
    console.log(chalk.red.bold('This is a bold red message!'));
    console.log(chalk.green.bgYellow('This is a green message with a yellow background!'));
    

How to Choose: ora vs chalk

  • ora:

    Choose ora if you need to indicate progress or loading states in your CLI application. It is particularly useful for long-running tasks where you want to provide users with feedback that the process is ongoing, helping to reduce uncertainty and improve the overall experience.

  • chalk:

    Choose chalk if you want to add color and style to your terminal output. It is ideal for highlighting messages, errors, or warnings in a visually appealing way, making your CLI applications more user-friendly and engaging.

README for ora

ora

Elegant terminal spinner



Install

npm install ora

Check out yocto-spinner for a smaller alternative.

Usage

import ora from 'ora';

const spinner = ora('Loading unicorns').start();

setTimeout(() => {
	spinner.color = 'yellow';
	spinner.text = 'Loading rainbows';
}, 1000);

API

ora(text)

ora(options)

If a string is provided, it is treated as a shortcut for options.text.

options

Type: object

text

Type: string

The text to display next to the spinner.

prefixText

Type: string | () => string

Text or a function that returns text to display before the spinner. No prefix text will be displayed if set to an empty string.

suffixText

Type: string | () => string

Text or a function that returns text to display after the spinner text. No suffix text will be displayed if set to an empty string.

spinner

Type: string | object
Default: 'dots'

The name of one of the provided spinners. See example.js in this repo if you want to test out different spinners. On Windows (except for Windows Terminal), it will always use the line spinner as the Windows command-line doesn't have proper Unicode support.

Or an object like:

{
	frames: ['-', '+', '-'],
	interval: 80 // Optional
}
color

Type: string | boolean
Default: 'cyan'
Values: 'black' | 'red' | 'green' | 'yellow' | 'blue' | 'magenta' | 'cyan' | 'white' | 'gray' | boolean

The color of the spinner. Set to false to disable coloring.

hideCursor

Type: boolean
Default: true

Set to false to stop Ora from hiding the cursor.

indent

Type: number
Default: 0

Indent the spinner with the given number of spaces.

interval

Type: number
Default: Provided by the spinner or 100

Interval between each frame.

Spinners provide their own recommended interval, so you don't really need to specify this.

stream

Type: stream.Writable
Default: process.stderr

Stream to write the output.

You could for example set this to process.stdout instead.

isEnabled

Type: boolean

Force enable/disable the spinner. If not specified, the spinner will be enabled if the stream is being run inside a TTY context (not spawned or piped) and/or not in a CI environment.

Note that {isEnabled: false} doesn't mean it won't output anything. It just means it won't output the spinner, colors, and other ansi escape codes. It will still log text.

isSilent

Type: boolean
Default: false

Disable the spinner and all log text. All output is suppressed and isEnabled will be considered false.

discardStdin

Type: boolean
Default: true

Discard stdin input (except Ctrl+C) while running if it's TTY. This prevents the spinner from twitching on input, outputting broken lines on Enter key presses, and prevents buffering of input while the spinner is running.

This has no effect on Windows as there is no good way to implement discarding stdin properly there.

Note: discardStdin puts stdin into raw mode. In raw mode, Ctrl+C no longer generates SIGINT from the terminal. Ora re-emits Ctrl+C from stdin input, but if your code blocks the event loop with synchronous work, Ctrl+C handling is delayed until the blocking work ends. Use async APIs, a worker thread, or a child process to keep Ctrl+C responsive, or set discardStdin to false.

Instance

.text get/set

Change the text displayed after the spinner.

.prefixText get/set

Change the text before the spinner.

No prefix text will be displayed if set to an empty string.

.suffixText get/set

Change the text after the spinner text.

No suffix text will be displayed if set to an empty string.

.color get/set

Change the spinner color.

.spinner get/set

Change the spinner.

.indent get/set

Change the spinner indent.

.isSpinning get

A boolean indicating whether the instance is currently spinning.

.interval get

The interval between each frame.

The interval is decided by the chosen spinner.

.start(text?)

Start the spinner. Returns the instance. Set the current text if text is provided.

.stop()

Stop and clear the spinner. Returns the instance.

.succeed(text?)

Stop the spinner, change it to a green and persist the current text, or text if provided. Returns the instance. See the GIF below.

.fail(text?)

Stop the spinner, change it to a red and persist the current text, or text if provided. Returns the instance. See the GIF below.

.warn(text?)

Stop the spinner, change it to a yellow and persist the current text, or text if provided. Returns the instance.

.info(text?)

Stop the spinner, change it to a blue and persist the current text, or text if provided. Returns the instance.

.stopAndPersist(options?)

Stop the spinner and change the symbol or text. Returns the instance. See the GIF below.

options

Type: object

symbol

Type: string
Default: ' '

Symbol to replace the spinner with.

text

Type: string
Default: Current 'text'

Text to be persisted after the symbol.

prefixText

Type: string | () => string
Default: Current prefixText

Text or a function that returns text to be persisted before the symbol. No prefix text will be displayed if set to an empty string.

suffixText

Type: string | () => string
Default: Current suffixText

Text or a function that returns text to be persisted after the text after the symbol. No suffix text will be displayed if set to an empty string.

.clear()

Clear the spinner. Returns the instance.

.render()

Manually render a new frame. Returns the instance.

.frame()

Get a new frame.

oraPromise(action, text)

oraPromise(action, options)

Starts a spinner for a promise or promise-returning function. The spinner is stopped with .succeed() if the promise fulfills or with .fail() if it rejects. Returns the promise.

import {oraPromise} from 'ora';

await oraPromise(somePromise);

action

Type: Promise | ((spinner: ora.Ora) => Promise)

options

Type: object

All of the options plus the following:

successText

Type: string | ((result: T) => string) | undefined

The new text of the spinner when the promise is resolved.

Keeps the existing text if undefined.

failText

Type: string | ((error: Error) => string) | undefined

The new text of the spinner when the promise is rejected.

Keeps the existing text if undefined.

spinners

Type: Record<string, Spinner>

All provided spinners.

FAQ

How do I change the color of the text?

Use chalk or yoctocolors:

import ora from 'ora';
import chalk from 'chalk';

const spinner = ora(`Loading ${chalk.red('unicorns')}`).start();

Why does the spinner freeze?

JavaScript is single-threaded, so any synchronous operations will block the spinner's animation. To avoid this, prefer using asynchronous operations.

Why do I get the line spinner on Windows Terminal or WSL?

Windows Terminal does not expose a reliable, stable way to detect itself or Unicode support from Node, and WT_SESSION is explicitly informative, not a detection API and can be inherited by other terminals. That makes environment-based detection best-effort. If you are in a Unicode-capable terminal, set spinner explicitly, for example ora({spinner: 'dots'}).

Can I log messages while the spinner is running?

Yes! Ora automatically handles writes to the same stream. The spinner will temporarily clear itself, output your message, and re-render below:

const spinner = ora('Processing...').start();

console.log('Step 1 complete');
console.log('Step 2 complete');

spinner.succeed('Done!');

The output will be clean with each log appearing above the spinner. This works seamlessly without requiring any special logging methods. Both console.log() (stdout) and console.error()/console.warn() (stderr) are supported.

[!NOTE] Don't run multiple spinners concurrently. Use one spinner at a time.

Can I display multiple spinners simultaneously?

No. Ora is designed to display a single spinner at a time. For multiple concurrent progress indicators, consider alternatives like listr2 or spinnies.

Can I use Ora with log-update?

Yes, use the .frame() method to get the current spinner frame and include it in your log-update output.

Does Ora work in Node.js Worker threads?

No. Ora requires an interactive terminal environment and Worker threads are not considered interactive, so the spinner will not animate. Run the spinner in the main thread and control it via worker messages:

// main.js
import {Worker} from 'node:worker_threads';
import ora from 'ora';

const spinner = ora().start();
const worker = new Worker('./worker.js');

worker.on('message', message => {
	switch (message.type) {
		case 'ora:text':
			spinner.text = message.text;
			break;
		case 'ora:succeed':
			spinner.succeed(message.text);
			break;
		case 'ora:fail':
			spinner.fail(message.text);
			break;
	}
});
// worker.js
import {parentPort} from 'node:worker_threads';

parentPort.postMessage({type: 'ora:text', text: 'Working...'});

// Do work...

parentPort.postMessage({type: 'ora:succeed', text: 'Done!'});

Related

Ports