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

tx-monitor

v1.1.0

Published

Real-time network traffic visualizer powered by tcpdump and WebSockets

Downloads

371

Readme

tx-monitor

A real-time network traffic visualizer.

Prerequisites

  • Bun
  • tcpdump (required for live capture only)

Quick Start

Use your preferred Node package management solution to execute the cli.

sudo bunx tx-monitor

Development

Run the WebSocket server and Vite dev server in separate terminals:

# Terminal 1 — replay from a log file
bun run monitor:file

# Terminal 2 — frontend with WebSocket proxy
bun run dev

Open http://localhost:4173.

For live capture instead of file replay:

bun run monitor

Live mode requires sudo access for tcpdump.

Production

Build the frontend, then start the Bun server (which serves dist/ and the WebSocket feed):

bun run build
bun run start:file   # or: bun run start

Open http://localhost:3001.

Native Executable

Build a standalone executable with the UI embedded:

bun run compile
./build/tx-monitor --file tcpdump.log   # or: sudo ./build/tx-monitor

Open http://localhost:3001. The compiled server embeds the React UI, so it does not need a sibling dist/ directory.

Scripts

| Script | Description | | --- | --- | | bun run dev | Vite dev server on port 4173 (proxies /ws to 3001) | | bun run build | Build browser bundle into dist/ | | bun run compile | Build native executable into build/tx-monitor with embedded UI | | bun run monitor | Start server with live tcpdump capture | | bun run monitor:file | Start server replaying tcpdump.log | | bun run start | Start server (live capture; serves dist/ if present) | | bun run start:file | Start server with --file tcpdump.log |

Server Options

bun run src/server.ts [--file <path>] [--port <port>] [--serve] [--db <path>] [--no-db] [--iface <name>] [--direction <dir>] [--bpf <expr>]

| Flag | Description | | --- | --- | | --file <path> | Replay a tcpdump log instead of live capture | | --port <port> | WebSocket and HTTP port (default: 3001) | | --serve | Serve the built frontend from dist/ | | --db <path> | SQLite database path for packet persistence (default: ~/.tx-monitor) | | --no-db | Disable SQLite persistence | | --iface <name> | Live capture interface (default: any) | | --direction <dir> | Live capture direction: in, out, or inout (default: out) | | --bpf <expr> | BPF filter for live (and basic post-filter for file replay), e.g. host 192.168.1.10 or port 53. Tokens starting with - are rejected. Live BPF is a single argv after --. |

Capture params (iface, direction, effective command, BPF) are surfaced in UI "Capture Source", status updates, and server logs. Controls in the sidebar let you change them at runtime for live capture (restarts subprocess cleanly) and apply basic BPF to file replays without full server restart. Session continuity preserved on live param changes.

Security: Runtime set-capture over WebSocket is an unauthenticated admin control (restarts sudo tcpdump). By default it is accepted only from loopback clients. Do not expose the server on untrusted networks. Set TXMON_ALLOW_REMOTE_CAPTURE=1 only if you intentionally allow remote capture control.

Configuration File

A local config file supplies safe defaults. Precedence is: config file < environment variables < CLI flags.

Primary location:

  • ~/.tx-monitor/config

Additional locations (later entries override earlier for the same key):

  • ~/.tx-monitor/config.toml
  • .tx-monitor/config (relative to current working directory)
  • .tx-monitor.toml (relative to current working directory)

File format is a simple KEY=VALUE file (comments with #, basic quoting supported, similar to dotenv). Only safe, non-secret keys are accepted.

Supported config keys (examples):

db=~/.tx-monitor
port=3002
file_replay_speed=1
file_replay_sleep_cap_ms=200
lsof_disable=0
lsof_interval_ms=2000
codex_timeout_ms=180000
codex_model=gpt-5.5

Secrets, credentials, API keys, and TXMON_TCPDUMP_ARGS are not allowed in the config file and are ignored if present (with a warning for secret-like or blocked keys). Keep credentials in the environment or .env.copilot only. Capture command args stay env-only so config files cannot change live tcpdump invocation.

A brief effective settings line is logged at startup (port, db, replay, mode). No new interactive settings UI is added.

Environment Variables

| Variable | Default | Description | | --- | --- | --- | | PORT | 3001 | Server listen port | | TXMON_DB | ~/.tx-monitor | SQLite database path when persistence is enabled | | TXMON_CODEX_AUTH | local | Codex SDK auth mode for copilot requests. Use local for your logged-in Codex/OpenAI subscription credentials, or api-key to pass OPENAI_API_KEY. | | OPENAI_API_KEY | unset | Optional key used only when TXMON_CODEX_AUTH=api-key. Can also be set in .env.copilot. | | TXMON_CODEX_MODEL | gpt-5.5 | Optional model override for Codex SDK copilot requests | | TXMON_CODEX_TIMEOUT_MS | 120000 | Timeout for backend Codex SDK copilot requests | | FILE_REPLAY_SPEED | 0 | Real-time replay multiplier for file mode (0 = send as fast as possible) | | FILE_REPLAY_SLEEP_CAP_MS | 120 | Max delay between replayed packets when FILE_REPLAY_SPEED is set | | TXMON_IFACE | any | Default live capture interface (overridden by --iface) | | TXMON_DIRECTION | out | Default live capture direction | | TXMON_BPF | (none) | Default BPF filter expression | | TXMON_TCPDUMP_ARGS | unset | Optional full live-capture argv (initial only; env only; not accepted in config files) | | TXMON_ALLOW_REMOTE_CAPTURE | unset | When 1/true, allow set-capture from non-loopback WebSocket clients (default: localhost only) |

Persistence

Captured packets are persisted to SQLite via Drizzle ORM using Bun's built-in driver. Persistence is enabled by default and writes to ~/.tx-monitor.

Read from another app (tx-mon-sdk)

Use the workspace package packages/tx-mon-sdk to open that SQLite file read-only and pull capture context around a timestamp (for dashboards / triage):

import { openTxMon } from "tx-mon-sdk";

const tx = openTxMon();
const ctx = tx.contextAround(eventAtMs, { windowMs: 30_000 });
tx.close();

See packages/tx-mon-sdk/README.md for the full query API.

Read over HTTP

| Endpoint | Description | | --- | --- | | GET /api/sessions | List recent capture sessions | | GET /api/sessions/:id | Fetch one capture session | | GET /api/sessions/:id/packets?offset=0&limit=5000 | Paginated packets for a session | | GET /api/packets?limit=80&session=<id> | List recent packets, optionally scoped to one session | | POST /api/copilot | Analyze the client-provided capture snapshot (strict snapshot model) using the backend Codex SDK |

Schema migrations live in drizzle/ and are applied automatically on server startup.

bun run db:generate   # regenerate migrations after schema changes

Testing

bun test

Project Layout

packages/
  tx-mon-sdk/          # Read-only SQLite SDK for capture context
src/
  App.tsx              # React UI and network diagram
  server.ts            # Bun WebSocket server
  db/                  # Drizzle ORM client/store (schema via tx-mon-sdk)
  tcpdumpParser.ts     # tcpdump line parser
  trafficNetwork.ts    # Application state
  layout.ts            # Host positioning
  index.tsx            # Browser entrypoint
drizzle/               # SQLite migrations
dist/                  # Generated build output