npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

logixia

v2.0.7

Published

Async-first TypeScript logger for Node, NestJS and the edge: request tracing, redaction, OpenTelemetry/OTLP export, file/database/cloud transports, sampling and log search. Winston/Pino alternative.

Readme

logixia


Why logixia

Most Node loggers give you a fast info() and leave the rest to you. logixia keeps the call simple and ships the parts you end up writing anyway:

  • Request tracing built in. Trace IDs travel through await via AsyncLocalStorage. Express and Fastify helpers read traceparent, x-request-id and friends, and every log line inside the request carries the ID.
  • Redaction before dispatch. Mask paths (*.password, req.headers.authorization) and regex patterns once, before any transport sees the entry. Transport credentials are also kept out of serialized output and error text.
  • Transports for real destinations. Console, rotating files, PostgreSQL, MySQL, MongoDB, SQLite, CloudWatch, Google Cloud Logging, Azure Monitor, Datadog, OTLP, Slack, Discord, and a worker-thread wrapper. Several can run on one log call.
  • OpenTelemetry-native. Read the active span for trace/log correlation, or export logs as OTLP/HTTP records. The OTLP transport builds the JSON itself, so no @opentelemetry/* SDK is required to emit logs.
  • Runs outside Node too. logixia/browser has no Node built-ins and is written for browsers and edge runtimes such as Cloudflare Workers.
  • Small footprint. Three runtime dependencies (commander, fast-json-stringify, picocolors), no install scripts, ESM and CommonJS builds with types.

Log calls are async and transport failures are caught internally, so a full disk or a flaky database does not crash your process.

Install

npm install logixia
# or: pnpm add logixia | yarn add logixia | bun add logixia

Node.js: the library declares node >=16 and is tested in CI on Node 18, 20 and 22. TypeScript 5.0+ is recommended for the bundled types. Building logixia from source needs a newer toolchain (Node ^22.19 || ^24.11 || >=26); see CONTRIBUTING.md.

Database transports use optional drivers that you install yourself: pg, mysql2, mongodb, or sqlite3 plus sqlite.

Quick start

import { createLogger, runWithTraceId } from 'logixia';

const logger = createLogger({
  appName: 'api',
  environment: 'development',
  traceId: true,
  redact: { paths: ['password'] },
});

await logger.info('Server started', { port: 3000 });

await runWithTraceId('req-8f3a', async () => {
  await logger.warn('Slow query', { table: 'orders', ms: 842 });
  await logger.info('Login', { user: 'alice', password: 'hunter2' });
});

await logger.error(new Error('Connection timeout'), { orderId: 'ord_123' });

Output (colors omitted, stack trace shortened):

[2026-10-30T14:24:30.621Z] [INFO] [api] [ec339fb5-5afb-4675-8c39-ecbad4353818] Server started {"port":3000}
[2026-10-30T14:24:30.623Z] [WARN] [api] [req-8f3a] Slow query {"table":"orders","ms":842}
[2026-10-30T14:24:30.623Z] [INFO] [api] [req-8f3a] Login {"user":"alice","password":"[REDACTED]"}
[2026-10-30T14:24:30.625Z] [ERROR] [api] [ec339fb5-5afb-4675-8c39-ecbad4353818] Connection timeout {"orderId":"ord_123","error":{"name":"Error","message":"Connection timeout","stack":"Error: Connection timeout\n    at main (...)"}}

Without a transports key logs go to the console. Add transports to write to files, databases or cloud services, all concurrently. There is also a ready-made default instance: import { logger } from 'logixia'.

→ Getting started · Configuration · Log levels

Feature tour

Request tracing

import { createExpressContextMiddleware, createLogger, getCurrentTraceId } from 'logixia';
import { createExpressMiddleware } from 'logixia/middleware';

const logger = createLogger({ appName: 'api', traceId: true });

app.use(createExpressContextMiddleware({ responseHeader: 'X-Trace-Id' }));
app.use(createExpressMiddleware(logger)); // one request/response log line per call

app.get('/orders', async (_req, res) => {
  await logger.info('Listing orders', { traceId: getCurrentTraceId() });
  res.json([]);
});

The trace ID is the first present header of traceparent (parsed to its 32-hex trace id), x-trace-id, x-request-id, x-correlation-id or trace-id, otherwise a generated UUID. Fastify has createFastifyContextHook() and createFastifyPlugin(); for anything else, wrap the handler in runWithTraceId(). logixia/correlation adds X-Correlation-ID propagation through fetch, axios, Kafka and SQS.

→ Tracing · HTTP logging · Child loggers and context

NestJS

Everything NestJS-specific lives in logixia/nest, so plain Node apps never load @nestjs/common.

import { Module } from '@nestjs/common';
import { LogixiaLoggerModule } from 'logixia/nest';

@Module({
  imports: [
    LogixiaLoggerModule.forRoot({
      appName: 'nestjs-api',
      traceId: true,
      transports: { console: {}, file: { filename: 'app.log', dirname: './logs' } },
    }),
  ],
})
export class AppModule {}

The module registers the trace middleware, provides LogixiaLoggerService for injection and also ships forRootAsync, @LogMethod(), LogixiaExceptionFilter, and Kafka and WebSocket trace interceptors. A full app with Docker Compose is in examples/nestjs-app.

→ NestJS guide

Redaction

const logger = createLogger({
  appName: 'api',
  redact: {
    paths: ['password', '*.token', 'req.headers.authorization', '**.creditCard'],
    patterns: [/Bearer\s+\S+/gi],
    censor: '[REDACTED]',
  },
});

await logger.info('Login', { user: 'alice', password: 'hunter2' });
// → {"user":"alice","password":"[REDACTED]"}

Paths support * (one segment) and ** (any depth), match case-insensitively, and the input object is never mutated. Circular references are printed as [Circular].

→ Redaction

Transports

All transports run concurrently. Built-in ones are configured under transports; the rest are classes you pass in transports.custom.

import { createLogger, OtlpLogTransport, SlackTransport } from 'logixia';

const logger = createLogger({
  appName: 'api',
  transports: {
    console: { level: 'info' },
    file: {
      filename: 'app.log',
      dirname: './logs',
      maxSize: '50MB',
      maxFiles: 14,
      zippedArchive: true,
    },
    custom: [
      new OtlpLogTransport({ url: 'http://localhost:4318/v1/logs', serviceName: 'api' }),
      new SlackTransport({ webhookUrl: process.env.SLACK_WEBHOOK_URL!, level: 'error' }),
    ],
  },
});

| Transport | Where it comes from | Use it for | | ----------------------------------------------------------------------------------- | ---------------------------------------------------- | -------------------------------------------------- | | Console | transports.console | Colorized dev output or JSON to stdout | | File | transports.file | Size/date rotation, gzip, retention | | Database | transports.database | PostgreSQL, MySQL, MongoDB, SQLite | | CloudWatch | logixia/cloudwatch | AWS CloudWatch Logs, optional EMF metrics | | Google Cloud | logixia/gcp | Cloud Logging with Cloud Trace correlation | | Azure Monitor | logixia/azure | Logs Ingestion API (Data Collection Rule) | | Datadog | transports.analytics.datadog, logixia/transports | Logs and metrics to Datadog | | OTLP | logixia, logixia/transports | OTLP/HTTP to Grafana, Axiom, SigNoz, a Collector | | Analytics | transports.analytics | Mixpanel, Segment, Google Analytics, Datadog | | Slack / Discord | logixia, logixia/transports | Alerting to a chat channel via webhooks | | Worker thread | logixia/worker | Move file/database/console I/O off the main thread | | Custom | transports.custom with ITransport | Anything else: S3, queues, internal services |

→ All transports

OpenTelemetry

import { createLogger, initOtelBridge } from 'logixia';

initOtelBridge(); // call once, after your OTel SDK starts

const logger = createLogger({ appName: 'checkout' });
await logger.info('Payment processed', { orderId: 'ord_123' });
// the active span's traceId and spanId are added to the entry

initOtelBridge() uses @opentelemetry/api when it is installed and does nothing when it is not. To export logs rather than only correlate them, add OtlpLogTransport (see Transports above). Ready-made OTLP configs for Grafana, Axiom, Better Stack and a local Collector are in the OTLP transport guide.

→ OpenTelemetry · OTLP transport

Browser and edge

import { createBrowserLogger } from 'logixia/browser';

const logger = createBrowserLogger({ appName: 'web', level: 'info' });
logger.info('Page loaded', { route: '/home' });

logixia/browser has no Node built-ins and ships a console transport plus a batching BrowserRemoteTransport that uses fetch. Working examples: examples/cloudflare-worker and examples/nextjs.

→ Browser and edge

Sampling and runtime levels

const logger = createLogger({
  appName: 'api',
  namespaceLevels: { 'db.*': 'debug', '*': 'info' },
  sampling: {
    rate: 0.1, // keep 10% in steady state
    traceConsistent: true, // keep or drop a whole trace together
    adaptive: { errorRateThreshold: 0.05, boostRate: 1.0, windowMs: 10_000 },
  },
});

When the windowed error rate crosses the threshold, the sample rate is raised until things calm down. You can also change levels in a running process: registerLevelSignal(logger) cycles the level on SIGUSR2, and createLevelControlHandler(logger) gives you an HTTP handler to mount behind your own auth.

→ Sampling · Log levels · Graceful shutdown

Metrics

import { createLogger, createMetricsPlugin } from 'logixia';

const metrics = createMetricsPlugin({
  http_requests_total: { type: 'counter', help: 'HTTP requests', labels: ['method', 'status'] },
});
const logger = createLogger({ appName: 'api' }).use(metrics);

await logger.info('request handled', { method: 'GET', status: 200 });
app.get('/metrics', metrics.expressHandler()); // Prometheus text format

→ Metrics

CLI and log search

npx logixia tail ./logs/app.log --follow --filter level:error
npx logixia search ./logs/app.log --query "payment failed"
npx logixia explore ./logs/app.log   # interactive terminal explorer

The CLI also has stats, analyze, export and query. For in-process search, logixia/search exports SearchManager, which indexes entries in memory and supports text, filters, natural-language queries and trace correlation.

→ CLI · Log search

More

Typed fields with createTypedLogger and defineLogSchema (typed logger), wide events / canonical log lines with wideEventMiddleware and addEventFields, a plugin API with onInit / onLog / onError / onShutdown hooks, and createMockLogger from logixia/testing for unit tests (testing).

Upgrading from 1.x

2.0 has one breaking change: everything NestJS-specific moved from the root entry to logixia/nest.

- import { LogixiaLoggerModule, LogMethod, InjectLogger } from 'logixia';
+ import { LogixiaLoggerModule, LogMethod, InjectLogger } from 'logixia/nest';

The root logixia entry no longer loads @nestjs/common, so Express, Fastify and plain Node apps work without NestJS installed. → Migration guide

Security

  • Redaction runs before any transport sees an entry, and HTTP logging redacts sensitive headers and query parameters by default.
  • Secrets stay out of output. Transport credentials (API keys, passwords, webhook URLs, tokens) are hidden from JSON.stringify, util.inspect and error messages.
  • Supply chain. Releases are published from CI with npm provenance through npm trusted publishing, so there is no long-lived npm token. The package has no install scripts and three runtime dependencies.
  • Reporting. Please report vulnerabilities privately through GitHub private vulnerability reporting. See SECURITY.md.

→ Security guide

Documentation and examples

| Topic | Link | | -------------------------------------------------------------------- | ---------------------------------------------------------------------------- | | Full documentation | logixia.github.io/logixia | | Configuration reference | guide/configuration | | API reference | guide/api | | Runnable examples (Express, Fastify, Hono, NestJS, Next.js, Workers) | examples/ | | Changelog | CHANGELOG.md |

Contributing

Pull requests are welcome. For larger changes, open an issue first. Setup, scripts and the commit convention are in CONTRIBUTING.md.

git clone https://github.com/Logixia/logixia.git
cd logixia
npm ci --ignore-scripts
npm test

Sponsor

logixia is free and MIT-licensed, and it is built and maintained by one person. If it saves you time, sponsoring keeps it moving:

npm fund logixia prints the same links.

License

MIT © Sanjeev Sharma