Skip to content

Repository files navigation

http-debugger

npm version CI License Downloads Docs

Zero-dependency HTTP debug middleware for Node.js, Deno, Bun, and the Edge.

Stop writing console.log(req.body) and stop switching to Postman to replay failed requests. http-debugger intercepts raw HTTP streams to give you safe, readable, and actionable terminal observability.

Please don't forget to support me with a star!

The Output

→ POST /api/users
  content-type: application/json
  authorization: ***

  Body: {
    "name": "Alice",
    "roles": ["admin", ... 2 more]
  }

← 500 Internal Server Error (45ms)
  content-type: application/json

  Body: { "error": "Database connection failed" }
  Size: 45B

  Timing:
    Headers:   1ms
    Body Read: 2ms
    Handler:   38ms
    Response:  4ms

  curl: curl -X POST 'http://localhost:3000/api/users' \
    -H 'content-type: application/json' \
    -d '{"name":"Alice"}'

Core Features

  • Instant Replay: Automatically generates ready-to-paste cURL commands for failed requests.
  • No Terminal Spam: Smart body truncation collapses deep JSON objects and massive arrays so your terminal stays readable.
  • Zero Dependencies: A tiny footprint that won't bloat your node_modules.
  • Framework Native: Ships with optimized adapters for Express, Fastify, Hono, and Next.js.
  • Edge Ready: The Hono adapter relies strictly on WinterCG standard Web APIs (performance.now(), ReadableStream), making it fully compatible with Cloudflare Workers, Deno, and Bun.

Installation

npm install http-debugger

Quick Start

Pick your framework. Register the middleware before your routes.

Express

import express from 'express';
import { httpDebugger } from 'http-debugger/express';

const app = express();
app.use(httpDebugger());

Fastify

import Fastify from 'fastify';
import { httpDebugger } from 'http-debugger/fastify';

const fastify = Fastify();
fastify.register(httpDebugger());

Hono

import { Hono } from 'hono';
import { httpDebugger } from 'http-debugger/hono';

const app = new Hono();
app.use('*', httpDebugger());

Astro

// src/middleware.ts
import { httpDebugger } from 'http-debugger/astro';

export const onRequest = httpDebugger();

```markdown
### Elysia (Bun)

```typescript
import { Elysia } from 'elysia';
import { httpDebugger } from 'http-debugger/elysia';

const app = new Elysia()
  .use(httpDebugger())
  .get('/', () => ({ hello: 'world' }))
  .listen(3000);

```markdown
### Next.js (App Router)

```typescript
// app/api/users/route.ts
import { withHttpDebugger } from 'http-debugger/next';

async function handler(req: Request) {
  return Response.json({ users: [] });
}

export const GET = withHttpDebugger(handler);

Mount the dashboard:

// app/__debugger/[[...route]]/route.ts
import { dashboardRoute } from 'http-debugger/next';

export const GET = dashboardRoute({ maxDepth: 4, sanitize: true });

Embedded Dashboard

http-debugger includes a real-time web dashboard accessible at /__debugger when enabled.

app.use(httpDebugger({ dashboard: true }));

Features:

  • Live stream — Real-time updates via SSE, no refresh needed
  • Filters — Method, status, duration (>500ms), size (<10KB), date range
  • Pause/Resume — Freeze the list without disconnecting SSE
  • Replay — Re-send any request with one click, see the new response inline
  • HAR Export — Full (Chrome DevTools compatible) or Minimal
  • Clear — Instant buffer reset
  • Auto-disabled in production (NODE_ENV=production)

Visit http://localhost:3000/__debugger to access the dashboard.

Configuration

Pass an options object to customize the behavior.

httpDebugger({
  // Show cURL command only when a request fails
  curl: (entry) => entry.response.statusCode >= 400,

  // Memory protection: max raw bytes to capture before dropping (default: 1024)
  maxBodySize: 2048,

  // Visual limits: collapse JSON deeper than 4 levels
  maxDepth: 4,

  // Visual limits: show only first 10 items of an array
  maxArrayItems: 10,

  // Automatically redact Authorization and Cookie headers
  sanitize: true,

  // Filter out noise (e.g., ignore health checks)
  filter: (entry) => !entry.request.path.includes('/health')
});
Option Type Default Description
filter (entry: DebugEntry) => boolean Only log entries that pass this check
maxBodySize number 1024 Max bytes to capture per body. Larger bodies are truncated.
maxDepth number 4 Max nesting depth before collapsing JSON objects.
maxArrayItems number 10 Max array items to show before truncating.
curl boolean | ((entry: DebugEntry) => boolean) false Show cURL command. Pass a function for conditional output.
sanitize boolean true Redact sensitive headers (Authorization, Cookie, etc.)
colors boolean auto Enable/disable ANSI color output. Auto-detects TTY.

How It Works

  1. The middleware wraps req.on() to intercept data and end events, collecting raw request body chunks.
  2. It wraps res.write() and res.end() to intercept response body chunks.
  3. A safety valve stops collecting once maxBodySize is reached — the stream continues flowing unmodified, so large responses (files, video, downloads) never cause memory issues.
  4. On response finish, it builds a DebugEntry with request, response, and timing data, then formats and logs it.

Why not Morgan / Pino?

Feature http-debugger Morgan Pino
Stream-level capture
Request body capture
Response body capture
Body truncation
cURL generation
Zero runtime deps
TypeScript support
Express
Fastify
Hono / Edge
Next.js (App Router)

Morgan is great for access logs in production, but it doesn't capture request/response bodies and has no truncation or cURL output.

Pino is a high-performance structured logger, but it's a different use case — it requires manual instrumentation and doesn't intercept streams automatically.

Contributing

Contributions welcome! See the contributing guide for setup, code style, and how to add a new adapter.

Quick start:

git clone https://github.com/nacimoualla/http-debugger.git
cd http-debugger
npm install
npm test

Exports

// Core
export { createTiming } from 'http-debugger';
export { generateId, captureRequestBody, captureResponseBody } from 'http-debugger';
export { formatEntry } from 'http-debugger';
export { sanitizeHeaders } from 'http-debugger';
export { createDashboardEngine, DASHBOARD_HTML } from 'http-debugger';
export type { DebugEntry, TimingInfo, MiddlewareOptions, CaptureResult, DashboardOptions } from 'http-debugger';

// Adapters
import { httpDebugger } from 'http-debugger/express';
import { httpDebugger } from 'http-debugger/fastify';
import { httpDebugger } from 'http-debugger/hono';

// Next.js
import { withHttpDebugger, dashboardRoute } from 'http-debugger/next';

License

MIT License with No-Resale Clause

This project is completely free to use internally to build, develop, test, and maintain commercial or personal products. However, you may not sell, lease, or sublicense this software itself (or a modified version of it) as a standalone commercial product. See the LICENSE file for full details.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages