TQDM-like progress bar for Node.js console applications
Full name: node-console-progress-bar-tqdm

This is a library that implements progress bar in console for Node.js in the style of
tqdm Python library.
This library implements very similar interface and options set.
Language support: TypeScript and JavaScript with CommonJS and EcmaScript modules.
Input data support: Array
, Number
, Generator
, AsyncGenerator
, Iterable
, Iterator
, AsyncIterable
, AsyncIterator
.
When Number
is passed as an input, there will be iterations over a range from 0 to this number.
Tested on Linux, macOS and Windows.
Node.js 16+ is required.
Table of contents
How does it look?
50% |ββββββββββββββββββββββββββββββββββββββββββββββββ | 50/100 [00:01.630<00:01.630, 0.033s/it]
https://github.com/andre487/node-console-progress-bar-tqdm/assets/1009104/afac1fe2-da92-433f-8791-4754f736feab
Quick examples
import {tqdm, TqdmProgress} from 'node-console-progress-bar-tqdm';
for (const item: number of tqdm([1, 2, 3, 4, 5])) {
doSomeWorkOn(item);
}
for (const idx: number of tqdm(100_000)) {
doSomeWorkOn(idx);
}
const inp1: Generator<Item> = itemGenerator();
for (const item: Item of tqdm(inp1)) {
doSomeWorkOn(item);
}
const inp2: AsyncGenerator<Item> = itemAsyncGenerator();
for await (const item: Item of tqdm(inp2, {total: 100})) {
doSomeWorkOn(item);
}
const pb = new TqdmProgress({
total: items.length,
progressColor: '#f1d3c4',
});
pb.render();
items.forEach((item) => {
doSomeWorkOn(item);
progressBar.update();
});
pb.close();
const res1 = TqdmProgress.withProgress((progressBar) => {
return items.map((item) => {
const res = doSomeWorkOn(item);
progressBar.update();
return res;
});
}, {total: items.length, progressColor: '$128'});
handleResult(res1);
const res2 = await TqdmProgress.withAsyncProgress(async (progressBar) => {
const res: HandledItem[] = [];
for await (const item of getAsyncItems()) {
res.push(await doSomeWorkOn(item));
progressBar.update();
}
return res;
}, {total: estimateItemsCount(), progressColor: '$200'});
handleResult(res2);
Installation
npm install --save node-console-progress-bar-tqdm
yarn add node-console-progress-bar-tqdm
pnpm install node-console-progress-bar-tqdm
Quick reference
This is a quick API reference. It's useful to look to some examples that are below.
export type TqdmUnitTable = Record<Intl.LDMLPluralRule, string>;
export type TqdmUnitOption = string | [string, string] | TqdmUnitTable;
export type TqdmOptions = {
description?: string;
maxColWidth?: number;
progressBraces?: [string, string];
progressSymbol?: string;
progressColor?: string;
initial?: number;
total?: number;
step?: number;
unit?: TqdmUnitOption;
unitScale?: boolean;
stream?: NodeJS.WritableStream,
minInterval?: number;
forceTerminal?: boolean;
};
export type TqdmInput = Iterable<unknown> |
Iterator<unknown> |
AsyncIterable<unknown> |
AsyncIterator<unknown> |
number;
export declare function tqdm<TInput extends TqdmInput>(input: TInput, opts?: TqdmOptions): Tqdm<TInput>;
export declare class Tqdm<TInput extends TqdmInput> implements Iterable<TqdmItem<TInput>>, AsyncIterable<TqdmItem<TInput>>, ITqdmSyncIteratorContainer<TqdmItem<TInput>>, ITqdmAsyncIteratorContainer<TqdmItem<TInput>> {
constructor(input: TInput, options?: TqdmOptions);
[Symbol.iterator](): TqdmSyncResultIteratorReturn<TInput>;
[Symbol.asyncIterator](): TqdmAsyncResultIteratorReturn<TInput>;
nextSync(): TqdmIteratorResultSync<TInput>;
nextAsync(): TqdmIteratorResultAsync<TInput>;
}
export declare class TqdmProgress implements ITqdmProgress {
constructor(options: TqdmOptions);
update(by?: number): void;
render(force?: boolean): void;
close(): void;
}
Examples
In these examples, besides the main goal, different input collections are illustrated
as well as different module types: TypeScript, EcmaScript modules, CommonJS modules.
You can run these examples from this repository:
cd example
npm ci
npm start
basic.cjs | Basic example | Iterate over an array without any options | CJS , Array , defaults |
generator.mjs | Generator examples | A couple of examples where we iterate over generator | ESM , Generator , with/without total |
countdown.mjs | Countdown | Countdown, progress bar changes from full to empty | ESM , Iterator , countdown |
unit-scaling.cjs | Unit scaling, range iteration | Example with iteration over number range defined by total with unit scaling (k,M,G,T) | CJS , Number , units , unit scaling |
custom-progress-bar.mts | Custom progress style | Fully customized progress bar written on TypeScript | TS , Generator , units , color , styling , max width |
sync-iterator-input.mts | Iteration over sync iterator | Example with Iterator and Iterable as input | TS , Iterable , color , styling |
async-iterator-input.mts | Iteration over async iterator | Example with AsyncIterator and AsyncIterable as input | TS , AsyncIterable , async , for/await , color , styling |
progress-with-no-iteration.cjs | Using progress bar directly | There is no iteration over tqdm iterator, direct TqdmProgress usage. Progress split to 2 parts | CJS , TqdmProgress , no tqdm() , flush output , resuming , color |
progress-with-no-iteration-ctx.mts | Using progress bar through context helpers | There is no tqdm function, using withProgress and withAsyncProgress helpers | TS , TqdmProgress , withProgress , withAsyncProgress , no tqdm() , color , styling , emoji |
direct-iteration.mts | Direct usage of Tqdm class | Very advanced example with direct Tqdm usage | TS , Generator , AsyncGenerator , async , async/await , no loop , units , color , styling |