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

server-devtools

v0.1.6

Published

Chrome DevTools for your backend. Inspect HTTP requests, database operations, outbound calls, errors, and execution timing from an embedded dashboard.

Readme

ServerDevTools

Chrome DevTools for your backend.

ServerDevTools is an embeddable backend inspector for Node.js applications: Chrome DevTools for your Node.js backend.

It gives you a live dashboard for inspecting:

  • incoming HTTP requests
  • request headers, params, query, and body
  • response status, headers, and body
  • execution flow
  • framework middleware and handlers
  • outgoing HTTP requests
  • database operations
  • errors
  • timing
  • current/authenticated user context
  • server-side request search
  • request filtering by HTTP method and status

Instead of jumping between logs, traces, and multiple observability tools, ServerDevTools lets you inspect what your backend is doing from one developer-focused interface.


Demo

ServerDevTools demo

POST /users
   │
   ├── Express middleware
   ├── Request handler
   ├── MongoDB query
   └── External HTTP request

Open:

http://localhost:3000/_devtools

and inspect the complete request lifecycle.


Why ServerDevTools?

Frontend developers have Chrome DevTools.

Backend debugging often looks like this:

console.log(...)
tail logs
search logs
inspect database
check external API logs
open tracing platform
repeat

ServerDevTools provides a simpler workflow:

Run request
     ↓
Open /_devtools
     ↓
Inspect what happened

It is designed for live backend debugging, not as a replacement for full production observability platforms.


Installation

npm install server-devtools

ServerDevTools includes the supported OpenTelemetry instrumentation libraries; you do not need to install the database instrumentation packages separately.


Quick Start

ServerDevTools uses an authenticated dashboard and stores inspection history in ./server-devtools.db by default, relative to the process working directory. Keep dashboard credentials and any encryption key in environment variables.

The encryption key must be a base64-encoded 32-byte key. Generate one with:

node -e 'console.log(require("node:crypto").randomBytes(32).toString("base64"))'

fields is optional. By default, ServerDevTools encrypts these field names:

  • password
  • accessToken
  • refreshToken
  • authorization
  • cookie

Specifying fields replaces the default list; it does not extend it.

To customize the encrypted fields:

encryption: {
  key: process.env.SERVER_DEVTOOLS_ENCRYPTION_KEY!,
  fields: ["password", "authorization", "apiKey"],
},

HTTP header redaction is enabled by default for sensitive header names such as authorization, proxy-authorization, cookie, set-cookie, and x-api-key. Add application-specific header names without replacing the defaults:

redaction: {
  additionalHeaders: ["x-access-token", "client-secret"],
},

Header redaction applies to header names only. It does not redact body fields, URLs, query parameters, or arbitrary span attributes.

getCurrentUser is optional. Use it when your application already exposes the authenticated user on the request; ServerDevTools does not require a Passport, JWT, or other authentication framework.

Node.js / Express TypeScript

Create server-devtools.ts:

import ServerDevTools from "server-devtools";

export const devtools = new ServerDevTools({
  auth: {
    username: process.env.SERVER_DEVTOOLS_USERNAME!,
    password: process.env.SERVER_DEVTOOLS_PASSWORD!,
  },
  encryption: {
    key: process.env.SERVER_DEVTOOLS_ENCRYPTION_KEY!,
  },
  getCurrentUser: (req) => req.user,
});

await devtools.start();
// src/main.ts
import { createServer } from "node:http";
import { devtools } from "../server-devtools";

const server = createServer((req, res) => {
  devtools.middleware(req, res, () => {
    res.statusCode = 404;
    res.end("Not found");
  });
});

server.listen(3000);
tsx watch --import ./server-devtools.ts src/main.ts

Data handling and privacy

ServerDevTools is an in-process developer inspector. Depending on the active instrumentation, request context, and framework integration, it can persist incoming request summaries and selected headers, paths and query attributes, parsed request bodies, response status/headers/bodies, database and Redis spans, outbound HTTP details, span errors and stack traces, and current-user data when getCurrentUser is configured. A category is not guaranteed for every request: preload order, active request context, framework parsers, and instrumentation-specific hooks determine what is available.

The only trace persistence provider currently implemented is local SQLite at ./server-devtools.db; the supported database and Redis instrumentations are capture sources, not telemetry storage providers. The SDK does not send telemetry to a ServerDevTools service or require an OpenTelemetry Collector. Use Clear History or delete an individual trace to remove trace data. There is no automatic trace retention or TTL. Dashboard sessions are stored separately, expire after 24 hours, and are removed on logout or expiry lookup.

Header-name redaction is enabled by default before captured HTTP details and HTTP span attributes are persisted. The defaults are authorization, proxy-authorization, cookie, set-cookie, and x-api-key; redaction's additionalHeaders extends that list. Names are trimmed, matched case-insensitively, and deduplicated. Redaction does not cover body fields, URLs, query parameters, or arbitrary non-header span attributes, and it does not rewrite existing records.

Optional AES-256-GCM encryption protects configured field names in supported metadata and outbound-detail records at rest. It is separate from redaction, does not encrypt the whole database or all span attributes, and authorized dashboard/API reads decrypt covered values. See the configuration reference, encryption guide, and security guidance for the exact coverage.

The fixed 256 KiB limit applies independently to native outbound request and response body capture. An oversized body is skipped rather than truncated; headers and the original network payload are preserved. Inbound response and fetch body capture do not currently have an SDK byte limit. Capture buffers or clones data, and persistence can add synchronous work; capture failures are isolated where implemented, but do not assume zero overhead or non-blocking behavior. Treat captured data and the embedded dashboard as sensitive in any shared or production-like environment.

await devtools.start() automatically registers OpenTelemetry's ESM loader hook once per process before starting the OpenTelemetry SDK. Keep startup in the preload module and let it complete before application dependencies load, including normal Redis (ioredis) imports. Already-loaded dependencies cannot be instrumented retroactively.

The installed OpenTelemetry hook exports asynchronous loader hooks, which require node:module.register(). Newer Node.js versions deprecate this API; its registerHooks() replacement takes synchronous hooks and cannot directly load OpenTelemetry's hook.mjs. This compatibility requirement does not change the startup command or configuration.

Why is initialization asynchronous?

await devtools.start() waits for the instrumentation startup contract. In the currently installed OpenTelemetry SDK, NodeSDK.start() performs registration synchronously; ServerDevTools then enables fetch capture before start() resolves. The async API keeps startup compatible with instrumentation work that may need to become asynchronous without changing application setup. It does not wait for application requests, database connections, or an external telemetry service.

Call it from the preload module before importing application dependencies. The instrumentations patch supported HTTP, framework, database, Redis, and Undici modules as they load, so modules imported first cannot be instrumented retroactively. Preloading adds startup work and startup failures can prevent the application from starting, but it ensures capture is installed before traffic begins.

The application can import the same instance normally and mount it in Express:

// src/main.ts
import express from "express";
import { devtools } from "../server-devtools";

const app = express();
app.use((req, res, next) => devtools.middleware(req, res, next));

app.get("/users/:id", async (req, res) => {
  res.json({ id: req.params.id, name: "John Doe" });
});

app.listen(3000);

Node.js / Express JavaScript

For JavaScript projects, create server-devtools.js:

const ServerDevTools = require("server-devtools");

const devtools = new ServerDevTools({
  auth: {
    username: process.env.SERVER_DEVTOOLS_USERNAME,
    password: process.env.SERVER_DEVTOOLS_PASSWORD,
  },
  encryption: {
    key: process.env.SERVER_DEVTOOLS_ENCRYPTION_KEY,
  },
  getCurrentUser: (req) => req.user,
});

module.exports = { devtools };

void devtools.start();

Preload the JavaScript file normally:

node --import ./server-devtools.js src/main.js

In the application, import the same instance and mount it with:

const express = require("express");
const { devtools } = require("../server-devtools.js");

const app = express();
app.use((req, res, next) => devtools.middleware(req, res, next));
app.listen(3000);

JavaScript projects do not need allowJs.

NestJS

NestJS uses a different preload pattern. Create a plain server-devtools.js outside src:

const ServerDevTools = require("server-devtools");

const devtools = new ServerDevTools({
  auth: {
    username: process.env.SERVER_DEVTOOLS_USERNAME,
    password: process.env.SERVER_DEVTOOLS_PASSWORD,
  },
  encryption: {
    key: process.env.SERVER_DEVTOOLS_ENCRYPTION_KEY,
  },
  getCurrentUser: (req) => req.user,
});

globalThis.__serverDevtools = devtools;

void (async () => {
  await devtools.start();
})();

Enable JavaScript files in the Nest TypeScript configuration:

{
  "compilerOptions": {
    "allowJs": true
  }
}

Start Nest with the preload file:

NODE_OPTIONS='--import ./server-devtools.js' nest start --watch

Do not create another ServerDevTools instance in main.ts. Retrieve the preloaded instance instead:

// src/main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { ServerDevToolsNestInterceptor } from "server-devtools/nestjs";
import ServerDevTools from "server-devtools";

declare global {
  var __serverDevtools: ServerDevTools | undefined;
}

async function bootstrap() {
  const devtools = globalThis.__serverDevtools;
  if (!devtools) {
    throw new Error(
      "ServerDevTools was not preloaded. Start Nest with NODE_OPTIONS='--import ./server-devtools.js'.",
    );
  }

  const app = await NestFactory.create(AppModule);
  app.use((req, res, next) => devtools.middleware(req, res, next));
  app.useGlobalInterceptors(
    new ServerDevToolsNestInterceptor(),
  );
  await app.listen(3000);
}

bootstrap();

This Nest-specific pattern initializes instrumentation before Nest and application dependencies load, while avoiding a second ServerDevTools initialization during watch mode.

Each example imports and mounts the same instance that was started by the preloaded initialization file. Its middleware serves the dashboard from the application's existing HTTP server at http://localhost:<your-port>/_devtools.

OpenTelemetry and outbound fetch capture start when devtools.start() is called; constructing the instance alone does not wrap globalThis.fetch.

Then open:

http://localhost:3000/_devtools

Make requests to your application and they will appear in the dashboard.


Examples

Working example applications are available if you want to see ServerDevTools integrated into a real project.

Express + TypeScript

server-devtools-express-ts

A minimal Express + TypeScript application showing ServerDevTools initialization, preloading, middleware mounting, encryption configuration, current-user capture, and request inspection.

NestJS

server-devtools-nestjs-test

A minimal NestJS application showing the ServerDevTools preload setup, middleware integration, NestJS error interceptor, encryption configuration, current-user capture, and request inspection.


Request Inspector

Inspect the incoming request, including:

  • method
  • path
  • route
  • headers
  • query parameters
  • route parameters
  • request body

Example:

{
  "name": "John Doe",
  "email": "[email protected]"
}

Response Inspector

Inspect what your application returned:

  • status code
  • response headers
  • response body

Example:

{
  "received": {
    "name": "John Doe",
    "email": "[email protected]"
  }
}

Execution View

ServerDevTools reconstructs the execution hierarchy for each request.

POST /users
│
├── Express middleware
├── Request handler
├── MongoDB query
└── HTTP request
    └── api.example.com

This makes it easier to understand what your backend executed during a request and where time was spent.


How It Works

ServerDevTools uses OpenTelemetry instrumentation to observe supported backend operations.

Application request and dependencies
    ↓
OpenTelemetry captures supported activity
    ↓
ServerDevTools maps captured spans and details
    ↓
Historical inspection data in SQLite
    ↓
Embedded dashboard on the application's HTTP server

OpenTelemetry provides the instrumentation layer. ServerDevTools provides the developer-focused inspection experience on top of it.


Embedded Dashboard

ServerDevTools does not require a separate dashboard server. It mounts directly into your existing application:

http://localhost:3000
│
├── /api/users
├── /api/orders
├── /api/...
└── /_devtools

Current Support

ServerDevTools currently supports:

  • Node.js
  • Express
  • NestJS middleware and error interception
  • MongoDB
  • PostgreSQL through pg
  • MySQL through mysql2
  • Redis (ioredis)
  • native HTTP/HTTPS and fetch/Undici requests, including headers and bodies
  • request search and filtering by HTTP method and status
  • current/authenticated user context when supplied by the application
  • OpenTelemetry-powered activity capture

Database tracing

Supported database operations automatically appear inside the request execution trace when using these supported drivers:

  • MongoDB
  • PostgreSQL (pg)
  • MySQL (mysql2)
  • Redis (ioredis)

Redis command spans include command inspection, arguments, timings, request links, and command errors. Redis (ioredis) support has been verified in Express and NestJS applications, including pipelines and transactions.


What ServerDevTools Is Not

ServerDevTools is not intended to replace full observability, monitoring, alerting, or log aggregation platforms.

Its focus is:

Interactive inspection of individual backend requests.


Development Status

ServerDevTools is currently under active development.

The first release focuses on making this workflow excellent:

Install ServerDevTools
        ↓
Initialize + preload ServerDevTools
        ↓
Start application
        ↓
Open /_devtools
        ↓
Run and inspect requests

Expect APIs and configuration to evolve before 1.0.


Coming next

Planned, not yet available:

  • Configurable trace storage, including storing ServerDevTools data through user-configured storage instead of only the default local SQLite storage

Security

ServerDevTools may capture sensitive application data, including request headers, request bodies, response bodies, database operations, and external request metadata.

Optional encryption at rest can protect configured fields in supported captured data. It does not redact all captured data or replace application security practices. The dashboard has authentication; use strong credentials and restrict access to /_devtools through your network and deployment setup.

Header-name redaction is available for configured HTTP headers, but body, URL, query-parameter, and arbitrary span-attribute redaction are not implemented. Capture-size limits apply only where documented by the SDK.


Philosophy

ServerDevTools should remain:

  • easy to install
  • easy to understand
  • framework-friendly
  • developer-focused
  • useful without requiring a full observability stack

The goal is simple:

Make backend debugging feel more like using browser DevTools.


Contributing

The project is still early.

Redis (ioredis) integration tests

The ioredis integration tests require a disposable Redis instance. Run them with its connection URL:

REDIS_TEST_URL=redis://127.0.0.1:6379 npx tsx --test tests/ioredis-integration.test.ts

When REDIS_TEST_URL is not set, the Redis integration tests are reported as skipped. The tests use isolated keys and clean up their clients and data.

Issues, ideas, bug reports, and contributions are welcome.


License

Apache-2.0