npm.io
3.0.0 • Published 11h ago

tilo

Licence
MIT
Version
3.0.0
Deps
5
Size
73 kB
Vulns
0
Weekly
6

tilo

build coverage mutation score version ESM TS license

This module is ESM . Please read this. Requires Node ≥ 22.

Tiny logger with styles and levels for Node.js / TypeScript — colorful, leveled output with per-level streams, a custom formatter, safe stringify, tables, traces, and a log event.

tilo output

Installation

npm i tilo

Quick Start

import { Tilo } from 'tilo';

const tilo = new Tilo({ level: 'debug' });

tilo.error('Something failed.');
tilo.warn('Heads up.');
tilo.info('Colorful, leveled output with date & time.');
tilo.debug('Visible because the level is "debug".');
tilo.silly('Hidden — below the active level.');

Guide

Formatted output

Provide a custom function that returns a formatted string:

tilo.format = (info, chalk) => {
  const text = `${info.time} ${info.level.toUpperCase()}\t${info.text}`;
  return info.level === 'error' ? chalk.red(text) : chalk.white(text);
};
tilo.info('Custom formatted log…'); // —» 15:30:43 INFO   Custom formatted log…
Safely stringified logs

Log safely-stringified objects (circular references handled). s() stringifies one or more values; sp() is the pretty/indented variant.

tilo.info(tilo.s({ key: 'stringify' }));
tilo.warn(tilo.sp({ key: 'stringify pretty' }));
Per-level streams

Route each level to its own stream — e.g. errors to stderr, everything else to stdout:

const tilo = new Tilo({
  streams: { default: process.stdout, error: process.stderr },
});

// a single stream is used as the default for every level:
tilo.streams = process.stdout;
Tables

Print a visual table from an array of rows:

tilo.table([
  ['Name', 'Score'],
  ['Ada', '99'],
  ['Linus', '95'],
]);
Clean stacks

Trim noise from error stacks — drop file-path-less frames, or filter by keyword:

const tilo = new Tilo({ cleanStack: true });            // drop internal/native frames
const t2 = new Tilo({ cleanStack: ['node_modules'] });  // drop frames matching keywords

tilo cleanStack — before & after

Emoji

Resolve an emoji by name (falls back to the :name: text on CI or when styles are off):

tilo.info('All done!', tilo.emoji('rocket'));
Configuration

Pass an options object to the constructor:

Option Type Default Description
enabled boolean true Whether log output is enabled.
level string "debug" Logging level — use the Tilo.Level enum.
format LogFormatFn Tilo.defaultFormat Formatting/styling function. Set to null to disable formatting.
styles boolean true Whether styles and colors are enabled.
streams ILogLevelStreams | NodeJS.WriteStream process.stdout Per-level write streams; a single stream becomes the default for every level.
cleanStack boolean | string[] false Remove file-path-less stack lines (true), or filter stacks by case-sensitive keywords (string[]).
Log levels & methods
Level Priority Methods Details
ERROR 0 error() Error logs. Always printed.
WARN 1 warn() Warning logs.
INFO 2 info() · ok() · plain() · table() Informational logs. ok() is an alias; plain() outputs clean unformatted text; table() prints a visual table from the given data.
VERBOSE 3 verbose() Verbose logs.
DEBUG 4 debug() · dir() · trace() Debug logs. dir() inspects an object; trace() appends a stack trace to the current position.
SILLY 5 silly() Silly logs.

There's also log(level, …args) (defaults to INFO), plus newline() and emoji(name):

tilo.log('debug', 'message…');
Log event

Tilo is an EventEmitter — run custom logic on the log event:

tilo.on('log', (logInfo) => {
  if (logInfo.level === 'error' && /\bfatal/i.test(logInfo.text)) {
    // e.g. send email to admin
  }
});

API

Beyond the level methods above:

Member Returns Description
log(level, …args) void Log at level; falls back to INFO if level is invalid.
table(data, options?) void Print a visual table (INFO).
dir(obj, options?) void Inspect an object and log it (DEBUG).
trace(…args) void Log with a stack trace to the current line (DEBUG).
newline() void Write a bare newline (no meta/format).
beep() void System beep, if the INFO stream is a TTY and not in CI.
s(…args) · sp(…args) string Safe stringify / pretty safe-stringify (handles circular refs).
emoji(name) string Resolve an emoji by name.
getStream(level) WritableStream The stream configured for a level.
isValidLevel(level) boolean Whether a string is a valid level.
Tilo.getPriorityOf(level) LogPriority (static) numeric priority of a level.
Tilo.defaultFormat LogFormatFn (static) the built-in formatter — assign back to format to restore it.

Every constructor option is also a live get/set accessor (enabled, level, format, styles, streams, cleanStack), plus the read-only priority, chalk, and isInCI.

Security & Quality

100% test coverage (lines/functions/statements/branches) verified by mutation testing (Stryker), enforced in CI across Node 20, 22, and 24.

Changelog

See CHANGELOG.md.

  • meow-styler — Colors & formatting for the meow CLI app helper.
  • perfy — Lightweight Node.js utility for measuring code execution in high-resolution real time.

License

2026, Onur Yıldırım. MIT License.

Keywords