ts-log

March 26, 2026 · View on GitHub

CI Downloads Version License StackGrit Score

A zero-dependency TypeScript logger interface. Let library consumers choose their own logger — or stay silent by default.

Installation

npm install ts-log

Usage

Accept a Logger in your library's constructor, defaulting to dummyLogger (which does nothing):

import { Logger, dummyLogger } from "ts-log";

class MyService {
  constructor(private readonly logger: Logger = dummyLogger) {}

  doWork() {
    this.logger.info("work started");
    // ...
    this.logger.debug("details", { foo: "bar" });
  }
}

Consumers can then pass in any compatible logger — or leave the default:

// silent by default
const service = new MyService();

// or use the built-in console
const service = new MyService(console);

// or use pino, bunyan, winston, etc.
import pino from "pino";
const service = new MyService(pino());

Logger Interface

The interface mirrors console — five methods, each accepting a message and optional parameters:

interface Logger {
  trace(message?: any, ...optionalParams: any[]): void;
  debug(message?: any, ...optionalParams: any[]): void;
  info(message?: any, ...optionalParams: any[]): void;
  warn(message?: any, ...optionalParams: any[]): void;
  error(message?: any, ...optionalParams: any[]): void;
}

Any object matching this shape works — no adapters needed. This includes console, pino, bunyan, winston, and most other Node.js loggers.

Custom Logger

You can implement the interface directly for custom behavior:

import fs from "node:fs";
import { Logger } from "ts-log";

class FileLogger implements Logger {
  private readonly fd: number;

  constructor(filename: string) {
    this.fd = fs.openSync(filename, "a");
  }

  trace(message?: any, ...params: any[]) {
    this.write("TRACE", message, params);
  }
  debug(message?: any, ...params: any[]) {
    this.write("DEBUG", message, params);
  }
  info(message?: any, ...params: any[]) {
    this.write("INFO", message, params);
  }
  warn(message?: any, ...params: any[]) {
    this.write("WARN", message, params);
  }
  error(message?: any, ...params: any[]) {
    this.write("ERROR", message, params);
  }

  private write(level: string, message: any, params: any[]) {
    fs.writeSync(this.fd, `${new Date().toISOString()} ${level} ${message} ${JSON.stringify(params)}\n`);
  }
}

v3 Migration

v3 is a tooling modernization — the Logger interface and dummyLogger API are unchanged.

  • Dual CJS/ESM package (via exports field).
  • "type": "module" added to package.json.
  • Minimum Node.js version is 20.
  • Build output moved from build/src/ to dist/.

License

MIT