A tiny, dependency-free (runtime) terminal progress logger with determinate bars, indeterminate loading animation, and ETA display — extracted from the user's custom implementation and packaged for npm.
npm i simple-progress-logger
const { Logger } = require('simple-progress-logger');
async function demo() {
const total = 50;
const log = new Logger({ message: 'Processing items…', total, barLength: 20 });
for (let i = 0; i <= total; i++) {
log.update('Crunching…', i);
await new Promise(r => setTimeout(r, 40));
}
log.stop('Done!');
}
demo();
import { Logger } from 'simple-progress-logger';
const total = 10;
const log = new Logger({ message: 'Indexing…', total });
let i = 0;
const interval = setInterval(() => {
i++;
log.increment();
if (i >= total) {
clearInterval(interval);
log.stop('Complete');
}
}, 100);
Options
message
(string): Label to show next to the bar/animation. Default''
.total
(number|null): Total units for determinate mode. Ifnull
, runs indeterminate animation. Defaultnull
.value
(number): Initial progress value. Default0
.showProgressBar
(boolean): Show determinate bar. Defaulttrue
.showLoadingAnimation
(boolean): Show indeterminate animation. Defaulttrue
.showEta
(boolean): Show ETA (only in determinate). Defaulttrue
.barLength
(number): Bar/animation width (chars). Default10
.updateThrottle
(number): Refresh interval (ms). Default50
.showAvgTimePerItem
(boolean): Append average seconds/item on stop. Defaultfalse
.fullCharacter
(string): Filled bar character. Default\u2588
.emptyCharacter
(string): Empty bar character. Default\u2591
.displayMessageFirst
(boolean): Put message before bar. Defaultfalse
.
Methods
update(message?: string, value?: number|null): this
— Update message and/or value.increment(): this
— Increment value by 1.stop(endMessage?: string): void
— Stop the logger and restore console output.
- Console methods (
log
,warn
,error
) are temporarily intercepted during determinate progress to keep the bar pinned while printing messages, then restored onstop()
. - Works in Node.js ≥ 16.
MIT © 2025 Dean Schulz