Architecture
RoxyProxy is a single Node.js process that runs the intercepting proxy, REST API, web UI, and background cleanup -- all on two ports.
Overview
┌─────────────────────────────────────────┐
│ RoxyProxy │
│ │
HTTP/S traffic │ ┌──────────────┐ ┌──────────────┐ │
─────────────────► │ │ Proxy Server │───►│ EventManager │ │
│ │ :8080 │ │ (pub/sub) │──┼──► SSE to Web UI
│ └──────┬───────┘ └──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ SQLite DB │◄───│ Cleanup │ │
│ │ (batched) │ │ (5 min) │ │
│ └──────┬───────┘ └──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ REST API │ │ Web UI │ │
│ │ /api/* │ │ (React) │ │
│ │ :8081 │ │ :8081 │ │
│ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────┘ Key Design Decisions
- SQLite with WAL mode -- high write throughput with concurrent reads. WAL (Write-Ahead Logging) allows the proxy to write captured requests while the API serves queries simultaneously without locking.
- Batched writes -- requests are queued in memory and flushed every 100ms to reduce I/O. This avoids a disk write per request during heavy traffic.
- Event batching -- SSE events are buffered for 100ms before flushing to connected clients. This prevents overwhelming the web UI during bursts of traffic.
- Response decompression -- gzip, deflate, and brotli responses are automatically decompressed before storage, so bodies are always readable.
- Body truncation -- configurable max body size prevents storage bloat. A
truncatedflag is set on affected records so you know when data was clipped. - Per-domain cert caching -- an LRU cache avoids regenerating SSL certificates for frequently accessed domains. Default capacity is 500 entries.
Data Storage
All data is stored in ~/.roxyproxy/data.db (SQLite). The requests table
has indexes on timestamp, host, status, path,
and content_type for fast querying.
Request and response bodies are stored as binary blobs. In the API and SSE stream, they are base64-encoded.
File Paths
| Path | Purpose |
|---|---|
~/.roxyproxy/data.db | SQLite database |
~/.roxyproxy/config.json | Configuration file (optional) |
~/.roxyproxy/ca/ca.crt | Root CA certificate |
~/.roxyproxy/ca/ca.key | Root CA private key |
~/.roxyproxy/pid | Process ID file |
Project Structure
src/
├── cli/ # CLI entry point, commands, interactive mode
│ ├── index.ts # Command registration (Commander.js)
│ ├── interactive.tsx # Interactive terminal menu (Ink/React)
│ ├── tail-ui.tsx # Real-time tail TUI (Ink/React)
│ ├── format.ts # Table/JSON output formatting
│ ├── commands/ # Individual CLI commands
│ └── system-proxy.ts # macOS system proxy & CA management
├── server/ # Proxy server, API, SSL, events
│ ├── index.ts # RoxyProxyServer orchestrator
│ ├── proxy.ts # HTTP/HTTPS intercepting proxy
│ ├── api.ts # Express REST API + SSE
│ ├── ssl.ts # CA generation & per-domain cert caching
│ ├── events.ts # Pub/sub event manager
│ └── config.ts # Config loading and merging
├── storage/ # Database and cleanup
│ ├── db.ts # SQLite operations (better-sqlite3)
│ └── cleanup.ts # Auto-cleanup job
├── shared/ # Shared TypeScript types
│ └── types.ts # Config, RequestRecord, RequestFilter
└── ui/ # React web UI (Vite)
├── App.tsx # Main app component
├── api.ts # API client + SSE hook
└── components/ # UI components Related
- REST API - Query captured traffic programmatically
- Configuration - Config file, storage limits, and auto-cleanup
- CLI Reference - All commands, flags, and output formats