v1.1.2 — stable

TypeScript logging
done right.

Async multi-transport logging — console, file, database, analytics — with a first-class NestJS module, request tracing, built-in search, and zero-dep OpenTelemetry. Replace winston and pino in one install.

$ npm install logixia
View on GitHub
logger.ts
import { createLogger, ConsoleTransport, FileTransport } from 'logixia';

const logger = createLogger({
  level: 'debug',
  transports: [
    new ConsoleTransport({ colorize: true, pretty: true }),
    new FileTransport({ filename: 'logs/app.log', rotate: true }),
  ],
});

// Structured logging — context travels with every log
const reqLogger = logger.child({ requestId: 'req-abc', userId: 42 });

reqLogger.info('User login', { method: 'oauth', provider: 'google' });
reqLogger.warn('Rate limit approaching', { remaining: 5, limit: 100 });
reqLogger.error('Payment failed', { orderId: 'ord-123', code: 'DECLINED' });
5
transport types
async
non-blocking I/O
0
prod dependencies
NestJS
first-class module
The Problem

Your current logger is holding you back.

winston needs 500 lines of config. pino is fast but inflexible. console.log doesn't scale. Every team ends up building a custom wrapper anyway.

Before — winston setup everyone dreads
old-logger.ts
// npm install winston winston-daily-rotate-file
// + configure, + wrapper, + NestJS adapter...
import * as winston from 'winston';

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.errors({ stack: true }),
    winston.format.splat(),
    winston.format.json()
  ),
  transports: [
    new winston.transports.Console({
      format: winston.format.combine(
        winston.format.colorize(),
        winston.format.simple()
      ),
    }),
    new (require('winston-daily-rotate-file'))({
      filename: 'logs/%DATE%.log',
      datePattern: 'YYYY-MM-DD',
      // ... 20 more options
    }),
  ],
}); // and you still need a NestJS adapter...
After logixia — one package, everything
logger.ts
// npm install logixia — that's it
import { createLogger, ConsoleTransport, FileTransport } from 'logixia';

const logger = createLogger({
  level: 'debug',
  transports: [
    new ConsoleTransport({ colorize: true }),
    new FileTransport({
      filename: 'logs/app.log',
      rotate: true,
      maxFiles: 7,
    }),
  ],
});

// NestJS? One import.
// import { LogixiaModule } from 'logixia/nest';

logger.info('Ready', { version: process.env.npm_package_version });
Features

Logging that scales with your app.

From local development to multi-service production. logixia grows with you without changing your API.

Async Multi-Transport

Log to console, rotating files, databases, analytics platforms, and custom webhooks — all asynchronously, in parallel, without blocking your event loop.

Console File Database Analytics Webhook

First-Class NestJS Module

Drop-in LogixiaModule with async configuration, DI support, per-module log levels, and request context propagation via AsyncLocalStorage.

LogixiaModule forRootAsync DI-ready

Built-in Log Search

Query your stored logs with full-text search, level filters, time ranges, and field conditions — without spinning up Elasticsearch. Works on any database transport.

full-text search time ranges field filters

OpenTelemetry Tracing

Automatic trace/span/parent correlation. Every log line carries traceId, spanId, and traceFlags — no extra packages needed.

traceId / spanId OTLP export zero deps

Request Context Tracing

logger.child() creates request-scoped loggers. Context fields (requestId, userId, tenantId) auto-attach to every log in that scope via AsyncLocalStorage.

child loggers AsyncLocalStorage request-scoped

Structured + Pretty

JSON in production, human-readable in development. Automatic log level colorization, timestamps, diff highlighting. One flag switches the output format.

JSON / pretty colorized timestamps

Webhook + Analytics Transports

Send error logs to Slack, PagerDuty, or any webhook. Ship analytics events to Segment, Mixpanel, or PostHog. Batched delivery with retry and backpressure.

Slack / webhook Segment batched

Log Levels + Sampling

Six levels: trace, debug, info, warn, error, fatal. Runtime level changes without restart. Sampling support — log only X% of debug events in high-throughput paths.

debug info warn error fatal

Custom Transport API

Extend with any transport by implementing the Transport interface. Two methods: write() and close(). Full TypeScript types.

extensible typed API 2-method interface
Code Examples

See it in action.

From basic setup to production-grade configuration.

logger.ts
import { createLogger, ConsoleTransport, FileTransport } from 'logixia';

const logger = createLogger({
  level: process.env.LOG_LEVEL ?? 'info',
  transports: [
    new ConsoleTransport({
      colorize: process.env.NODE_ENV !== 'production',
      pretty: process.env.NODE_ENV !== 'production',
    }),
    new FileTransport({
      filename: 'logs/app.log',
      rotate: true,
      maxSize: '20m',
      maxFiles: 14,
    }),
  ],
});

logger.info('Server started', { port: 3000, env: process.env.NODE_ENV });
logger.warn('Config missing', { key: 'REDIS_URL', fallback: 'localhost' });
logger.error('Unhandled error', { stack: err.stack, context: 'app' });
app.module.ts
import { Module } from '@nestjs/common';
import { LogixiaModule } from 'logixia/nest';
import { ConsoleTransport, FileTransport } from 'logixia';
import { ConfigService } from '@nestjs/config';

@Module({
  imports: [
    LogixiaModule.forRootAsync({
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        level: config.get('LOG_LEVEL', 'info'),
        transports: [
          new ConsoleTransport({ colorize: config.get('NODE_ENV') !== 'production' }),
          new FileTransport({ filename: 'logs/nest.log', rotate: true }),
        ],
      }),
    }),
  ],
})
export class AppModule {}

// In your service:
@Injectable()
export class UserService {
  constructor(private readonly logger: LogixiaLogger) {}

  async findUser(id: string) {
    this.logger.debug('Finding user', { id });
    // logger automatically carries the request context
  }
}
multi-transport.ts
import {
  createLogger,
  ConsoleTransport,
  FileTransport,
  DatabaseTransport,
  WebhookTransport,
  AnalyticsTransport,
} from 'logixia';

const logger = createLogger({
  level: 'debug',
  transports: [
    // Dev console with colors
    new ConsoleTransport({ colorize: true, pretty: true }),

    // Rotating file logs
    new FileTransport({ filename: 'logs/app.log', rotate: true, maxFiles: 7 }),

    // Persist errors to DB for search
    new DatabaseTransport({
      adapter: 'postgres',
      connectionString: process.env.DATABASE_URL!,
      minLevel: 'warn',
      tableName: 'application_logs',
    }),

    // Slack alerts for errors
    new WebhookTransport({
      url: process.env.SLACK_WEBHOOK_URL!,
      minLevel: 'error',
      batch: { size: 5, intervalMs: 1000 },
    }),

    // Analytics events
    new AnalyticsTransport({
      provider: 'segment',
      writeKey: process.env.SEGMENT_WRITE_KEY!,
      minLevel: 'info',
    }),
  ],
});
request-context.ts
import { createLogger, createRequestContext } from 'logixia';
import type { Request, Response, NextFunction } from 'express';

const logger = createLogger({ level: 'info', transports: [...] });

// Express middleware — attaches context to every log in this request
export function requestLogger(req: Request, res: Response, next: NextFunction) {
  const ctx = createRequestContext({
    requestId: req.headers['x-request-id'] as string ?? crypto.randomUUID(),
    userId: req.user?.id,
    tenantId: req.headers['x-tenant-id'] as string,
    ip: req.ip,
    method: req.method,
    path: req.path,
  });

  // reqLogger carries all context fields automatically
  const reqLogger = logger.withContext(ctx);
  req.logger = reqLogger;

  reqLogger.info('Request started');

  res.on('finish', () => {
    reqLogger.info('Request completed', {
      status: res.statusCode,
      duration: Date.now() - req.startTime,
    });
  });

  next();
}
custom-transport.ts
import { Transport, LogEntry } from 'logixia';

// Implement 2 methods. That's all.
class DatadogTransport implements Transport {
  private readonly apiKey: string;

  constructor({ apiKey }: { apiKey: string }) {
    this.apiKey = apiKey;
  }

  async write(entry: LogEntry): Promise<void> {
    await fetch('https://http-intake.logs.datadoghq.com/v1/input/' + this.apiKey, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        level: entry.level,
        message: entry.message,
        timestamp: entry.timestamp,
        ...entry.fields,
      }),
    });
  }

  async close(): Promise<void> {
    // flush pending batches
  }
}

// Use like any built-in transport
const logger = createLogger({
  transports: [new DatadogTransport({ apiKey: process.env.DD_API_KEY! })],
});
Transports

One logger. Every destination.

logixia routes each log to every transport in parallel. Failures in one transport never affect the others.

ConsoleTransport

Colorized, pretty-printed output for local dev. JSON mode for production log aggregators (Datadog, Grafana Loki).

FileTransport

Rotating log files with size and date-based rotation, compression, and configurable retention. Buffered writes for performance.

DatabaseTransport

PostgreSQL, MySQL, MongoDB, SQLite adapters. Enables built-in log search. Schema auto-migration included.

WebhookTransport

POST logs to Slack, PagerDuty, Discord, or any HTTP endpoint. Batched delivery with retry and per-level filtering.

AnalyticsTransport

Ship log events to Segment, Mixpanel, PostHog, or Amplitude. Maps log fields to analytics event properties automatically.

Custom Transport

Implement the Transport interface. Two methods: write() and close(). Send logs anywhere.

Comparison

How logixia stacks up.

Every missing feature in the table below represents something your team builds and maintains manually.

Feature logixia winston pino bunyan
TypeScript-first~~
NestJS module~~
Async transports~
Database transport~~
Built-in log search
OpenTelemetry tracing~
Request context
Webhook / analytics transport
File rotation built-in~~~
Zero prod dependencies~

~ partial/via plugin  ·  ✓ built-in  ·  ✗ unavailable

Get Started

Up and running in 60 seconds.

npm
npm install logixia
pnpm
pnpm add logixia
yarn
yarn add logixia
bun
bun add logixia
quickstart.ts
import { createLogger, ConsoleTransport } from 'logixia';

// 1. Create a logger — export and share it
const logger = createLogger({
  level: 'debug',
  transports: [new ConsoleTransport({ colorize: true })],
});

// 2. Log with structured context
logger.info('App started', { version: '1.0.0', port: 3000 });

// 3. Create request-scoped child loggers
const reqLogger = logger.child({ requestId: 'abc-123', userId: 42 });

reqLogger.debug('Processing request');
reqLogger.warn('Slow query detected', { duration: 1240, query: 'SELECT ...' });

// All logs from reqLogger automatically include requestId and userId

Stop configuring
your logger.

logixia gives you async multi-transport, NestJS integration, request tracing, and search out of the box. One package. Done.