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

@devlite/nodejs

v0.1.4

Published

DevLite Node.js SDK — AI-powered observability with 1-3 line integration. Automatic error grouping, source context, user impact tracking, and sensitive-data scrubbing built in.

Readme

@devlite/nodejs

AI-powered observability SDK for Node.js. Add two lines, get automatic request tracking, error capture, error grouping, source context, user tracking, distributed tracing, fast database insights, and slow-endpoint detection — no config files, no manual instrumentation.

Try it in 60 seconds

git clone https://github.com/Ishimwe-Kevin/devlite-app
cd devlite-app/devlite-sdk/examples/demo-express
npm install
npm start          # terminal 1 — instrumented Express "checkout" service
npm run demo       # terminal 2 — generates realistic traffic & bugs

The demo app contains two intentional bugs plus a slow endpoint, so the dashboard fills with grouped errors, source context, user impact, and metrics — perfect for a live walkthrough. Point it anywhere with DEVLITE_API_KEY / DEVLITE_ENDPOINT.

Install

npm i @devlite/nodejs

60-second quickstart

const devlite = require('@devlite/nodejs');

devlite.init({ apiKey: 'dl_live_xxxxx' });

That's it — every HTTP request, uncaught exception, and unhandled promise rejection is now captured automatically, with:

  • Grouped errors — the same bug occurring 1,000 times shows up as one issue, not 1,000
  • Real source code context — the actual lines around the crash, not just a stack trace
  • Automatic sensitive-data scrubbing — emails, tokens, passwords redacted before anything leaves your process
  • User impact tracking — know exactly which users hit which bugs

Point apiKey/endpoint at the hosted platform (default) or your own DevLite ingest API — see devlite-ingest-api in this repo.

Full usage

Distributed tracing — zero config

Every request the SDK sees is a trace. Outbound http/https (including anything built on them: Axios, got, node-fetch…) and global fetch calls made while handling that request automatically get a W3C traceparent header pointing at the same trace, so any downstream service — DevLite or OpenTelemetry-compatible — joins the same trace across the wire. Each outbound call is also recorded as a child span (http_out/fetch) with host, status code and latency, giving the dashboard a real per-request waterfall.

devlite.init({ apiKey: 'dl_live_xxxxx' });
// that's it — every axios/got/fetch/http call is now traced, across services

Inbound requests already carrying a traceparent header (from a caller on DevLite, or any OTel propagator) continue that trace instead of starting a new one.

Automatic database instrumentation — the "I can't live without this" part

The most common Node drivers are instrumented automatically — no wrappers, no work:

  • pg (Client.query)  ·  mysql2 (Connection.query/execute)  ·  better-sqlite3 (statement.run/get/all/iterate)

Every query executed inside a traced request becomes a child span carrying the (scrubbed) SQL, its duration, and — when it's slower than sqlSlowThresholdMs (default 500ms, exactly the level the backend flagger uses) — a slow_request receipt. That's the exact data that powers the dashboard's slow-query, "add an index", and N+1 findings. Patch uses the app's node_modules, so it works even if you haven't linked the SDK.

Drivers we can't auto-patch (Prisma, Sequelize, Knex, mongoose…)? One line:

devlite.trackSql({ query: 'SELECT * FROM users WHERE id = $1', durationMs: 620, params: ['42'] });

Express (recommended add-on)

The core patch works with any framework, but adding the Express middleware upgrades data quality by resolving matched routes (/users/:id) instead of raw URLs (/users/8123):

const express = require('express');
const devlite = require('@devlite/nodejs');

devlite.init({ apiKey: 'dl_live_xxxxx' });

const app = express();
app.use(devlite.expressMiddleware());

app.get('/users/:id', (req, res) => { /* ... */ });

// Add AFTER all routes:
app.use(devlite.expressErrorHandler());

Configuration options

devlite.init({
  apiKey: 'dl_live_xxxxx',        // required
  environment: 'production',       // default: process.env.NODE_ENV
  serviceName: 'payments-api',      // default: current folder name
  release: 'v2.1.3',                // e.g. git sha, shown in deployment views
  beforeSend: (event) => event,     // run on EVERY event right before enqueue. Return the
                                    // (possibly mutated) event to keep it, or null to drop it.
                                    // A throwing hook drops the event — never crashes the SDK.
  sampleRate: 1.0,                  // 0.0–1.0, lower on very high-traffic services.
                                    // Sampling is COHERENT: a sampled-out request drops its
                                    // errors/spans/logs/metrics together. Deployments and
                                    // out-of-request crashes (uncaught exceptions) always survive.
  distributedTracing: true,          // emit + accept W3C traceparent: end-to-end traces across
                                    // every process/service. The one line that makes DevLite
                                    // trace-first without being locked in.
  autoInstrumentSql: true,          // auto-patch pg / mysql2 / better-sqlite3. Turn off only
                                    // if you prefer manual trackSql() everywhere.
  sqlSlowThresholdMs: 500,          // queries slower than this emit a slow_request (the same
                                    // threshold the backend recommendation engine uses).
  slowRequestMs: 1000,              // HTTP requests slower than this are flagged as slow.
  requestTimeoutMs: 10000,          // hard timeout per ingest flush so a dead endpoint can't
                                    // hang your app.
  captureSourceContext: true,       // attach the actual surrounding source code to errors
  scrubSensitiveData: true,         // auto-redact emails, JWTs, tokens, credit cards, etc.
  captureConsoleBreadcrumbs: true,  // console.warn/error already in your code become breadcrumbs
  captureConsoleLogs: true,         // ALSO forward console.* as `log` events so the dashboard's
                                    // Logs stream works out of the box (set false to silence noisy apps)
  captureBody: false,               // capture request headers (redacted) — off by default
  flushIntervalMs: 5000,            // how often batched events are sent
  gzip: true,                       // compress request bodies (Content-Encoding: gzip) — cuts bandwidth 10-20x
  debug: false,                     // log SDK internals to console
  onError: (err) => { /* SDK-internal send failures, e.g. for your own logging */ },
});

Manual capture API

Auto-instrumentation covers most cases, but you can add explicit signal too:

// Capture a handled error with extra context
devlite.captureError(err, { userId: '123', action: 'checkout' });

// Log a non-error event
devlite.captureMessage('Payment retried after timeout', 'warning');

// Report a custom metric — feeds forecasting/anomaly detection
devlite.reportMetric({ name: 'order.total', value: 42.5, unit: 'USD', tags: { region: 'lagos' } });

// Capture a structured log line with arbitrary fields
devlite.captureLog('checkout completed', 'info', { orderId: 'ord_123', durationMs: 250 });

// Trace a unit of work as a span
const span = devlite.startSpan('checkout.process', { traceId: 'abc', parentId: 'def' });
span.end('ok'); // 'ok' | 'error' — sends { name, durationMs, status, ... }
devlite.reportSpan({ name: 'db.query', durationMs: 120, status: 'error', tags: { table: 'orders' } }); // or manual

// Tell DevLite about a deployment (powers before/after performance views)
devlite.reportDeployment({ version: 'v2.1.3', commitSha: 'a1b2c3d' });

// Add a breadcrumb — recent breadcrumbs are attached to the next captured error,
// which significantly improves the AI's root-cause explanation.
devlite.addBreadcrumb({ type: 'business_event', note: 'user started checkout' });

// Tag all subsequent events — tags are merged into each error's `extra`,
// so the dashboard shows your context alongside the message.
devlite.setTag('region', 'lagos');
devlite.setTag('deploy', 'canary');

// Host metrics — CPU / RSS / uptime streamed as `metric` events
const host = devlite.startHostMetrics({ intervalMs: 15000 }); // options optional
// host.stop();  — stop collecting

// Proof-of-life: verify the SDK → ingest pipeline in a health check or on startup
const health = await devlite.checkConnectivity();
console.log(health.ok, health.accepted, health.quota, health.latencyMs);

// Introspect: see what's going on under the hood at any time
console.log(devlite.getStats());
// { lastAccepted: 3, lastQuota: 1000, droppedCount: 0, lastErrorAt: null, lastFlushMs: 42, queued: 0 }

Serverless / short-lived processes

Since events are batched, call flush() before your function returns to make sure nothing is lost:

await devlite.flush();

Graceful shutdown

The SDK automatically flushes on SIGTERM/SIGINT. If you manage shutdown yourself, call:

await devlite.close();

What gets sent

  • HTTP requests: method, path, status code, duration, traceId + spanId
  • Slow requests (>1s): flagged separately for APM analysis
  • Outbound HTTP/fetch child spans (http_out/fetch): host, method, status, duration — automatically part of the request's trace
  • Database query spans (kind: sql): the scrubbed SQL text, duration, status — automatically feeds slow-query / missing-index / N+1 AI recommendations
  • Errors: message, stack trace, recent breadcrumbs, route + method (when in a request)
  • Metrics: custom name/value/unit/tags via reportMetric()
  • Structured logs: level + message + fields via captureLog()
  • Trace spans: name, timing, traceId, parentId via startSpan()/reportSpan()/auto-patch
  • Deployments, manual messages, and tags (if you call the relevant methods)
  • Host metrics (CPU, RSS, uptime) via startHostMetrics({ intervalMs }) — streamed as metric events
  • Ingest ack stats (accepted, quota): surfaced in getStats() so you know whether the pipeline is clean

Request/response bodies and most headers are not captured unless you explicitly set captureBody: true — and even then, sensitive headers (authorization, cookie, x-api-key) are redacted by default.

What makes this competitive (vs. bolt-on monitoring tools)

  • Distributed tracing that requires zero thought. Every outbound http/https/fetch call made while handling a request automatically gets a W3C traceparent header — no manual setSpan() wrapping, no context-propagation boilerplate, no lock-in to a single transport. Request-carrying apps, background workers, microservice meshes: it just works. Sentry, Rollbar, Bugsnag don't offer this.
  • Automatic database instrumentation that powers AI recommendations, not just dashboards. pg/mysql2/better-sqlite3 queries become sql-tagged spans the instant the SDK is mounted. The dashboard's slow-query, "add an index" and N+1 detection work out of the box — no log parsing, no log-histogram guessing. The 500ms threshold matches the backend engine exactly.
  • Proof-of-life and intake visibility. checkConnectivity() hits the ingest endpoint on startup and returns whether the pipeline is alive — no logs to grep, no separate health check. getStats() surfaces lastAccepted, lastQuota, and droppedCount so you can prove data integrity in a status page or runbook.
  • Automatic error grouping — the same underlying bug, however many times it fires, is fingerprinted and grouped into one issue with an occurrence count, instead of flooding your dashboard with duplicates.
    devlite.captureError(err); // auto-grouped by error type + message + stack shape
    devlite.captureError(err, { fingerprint: 'payment-timeout' }); // or force your own grouping key
  • Source code context — every captured error includes the actual lines of code around the crash, read live from disk, not just a bare stack trace.
  • User impact tracking — devlite.setUser({ id, email }) scopes to the current request (via AsyncLocalStorage, so concurrent requests never leak each other's identity) and tags every error captured during it, directly answering "which users are affected?"
    app.use((req, res, next) => {
      devlite.setUser({ id: req.user.id, email: req.user.email });
      next();
    });
  • Automatic console breadcrumbs — console.warn/console.error calls you already have in your code automatically become breadcrumbs attached to the next error, with zero extra instrumentation.
  • beforeSend everywhere — the Sentry-style event hook runs on every event right before enqueue: mutate to enrich, return null to drop (e.g. filter out health-check noise), and a throwing hook degrades to "drop the event" instead of crashing your app.
  • Automatic sensitive-data scrubbing — on by default. Emails, JWTs, bearer tokens, AWS keys, credit card numbers, and any field literally named password/token/secret/etc. are redacted before anything leaves your process — even inside nested objects and source code snippets. Disable only if you're certain you want raw data: captureSourceContext/scrubSensitiveData config flags.

Design principles

  • Never blocks your app. All sends are async, batched, and retried with backoff. If DevLite's backend is unreachable, your app keeps running.
  • Never swallows errors. DevLite observes errors, it doesn't intercept or suppress them — your existing error handling behaves exactly as before.
  • Bounded memory. The internal queue has a hard size cap; if the network is down for a long time, oldest events are dropped rather than growing memory unbounded.

License

MIT