reprokit
v0.2.0
Published
Capture production error context and replay bugs locally via CLI
Maintainers
Readme
ReproKit
Capture production error context and replay bugs locally in one command.
Stop deploying logging hotfixes to debug production issues. ReproKit captures the full request context when errors happen and gives you a ready-to-paste curl command to reproduce it locally.
Install
npm install reprokitQuick Start
import express from 'express'
import { reprokit } from 'reprokit'
const app = express()
app.use(express.json())
const rk = reprokit()
// Add error handler after your routes
app.use(rk.errorHandler)Trigger an error, then:
npx reprokit list # see captured errors
npx reprokit inspect <id> # full error context
npx reprokit curl <id> # ready-to-paste curl command
npx reprokit replay <id> # replay against localhostWhat It Captures
When a 5xx error or unhandled exception occurs, ReproKit saves:
- Full request (method, URL, headers, body)
- Full response (status, headers, body)
- Error stack trace
- Environment (Node version, OS, memory, feature flags, git SHA)
- APM correlation IDs (Sentry, Datadog)
All captured data is stored locally in SQLite. Nothing leaves your machine.
Catch Silent Failures (200s with wrong data)
Some bugs don't throw errors. Use captureWhen to catch 200 responses that look wrong:
const rk = reprokit({
captureWhen: (req, res, body) => {
// Capture when /api/charges returns an empty array
if (req.url === '/api/charges' && Array.isArray(body) && body.length === 0) {
return true
}
return false
}
})
// Add interceptor BEFORE routes
app.use(rk.interceptor)
// Add error handler AFTER routes
app.use(rk.errorHandler)Manual Capture
For cases where you know something is wrong:
app.post('/api/charge', (req, res) => {
const result = processPayment(req.body)
if (result.status === 'failed') {
rk.capture(req, res, new Error(`Payment failed: ${result.reason}`))
}
res.json(result)
})CLI Commands
| Command | Description |
|---------|-------------|
| reprokit list | Show recent captured errors |
| reprokit inspect <id> | Pretty-print full capture details |
| reprokit curl <id> | Output a ready-to-paste curl command |
| reprokit replay <id> | Replay request against a local server |
| reprokit export <id> | Export capture to shareable JSON file |
| reprokit import <path> | Import captures from JSON file or directory |
| reprokit test | Create a synthetic capture to verify setup |
| reprokit init | Set up data directory and .gitignore |
| reprokit uninstall | Remove captured data and clean up |
Sanitization
ReproKit automatically redacts sensitive data:
Headers (default blocklist): Authorization, Cookie, Set-Cookie, X-API-Key
Body fields (default blocklist): password, secret, token, card_number, ssn, credit_card, api_key, access_token, private_key
Customize blocklists:
const rk = reprokit({
sanitize: {
headerBlocklist: ['authorization', 'x-custom-secret'],
bodyFieldBlocklist: ['password', 'ssn', 'my_secret_field'],
}
})Configuration
reprokit({
dbPath: '.reprokit/captures.db', // SQLite database location
maxBodySize: 1024 * 1024, // 1MB max body capture (default)
maxCaptures: 1000, // Auto-prune after 1000 captures (default)
debug: true, // Log capture activity to stderr
})Environment variables:
REPROKIT_DB_PATH— Override database pathREPROKIT_DEBUG=true— Enable debug output
Deduplication
Repeated errors are automatically deduplicated using stack-frame fingerprinting. The same error on the same code path is counted, not duplicated:
POST /api/charge 500 PaymentError — seen 47 times, last: 2min agoSharing Captures
Export a capture and share it with a teammate:
npx reprokit export <id> -o bug-report.json
# Share bug-report.json via Slack, email, or GitHub issue
# Teammate imports it:
npx reprokit import bug-report.json
npx reprokit curl <id> # instant curl commandMulti-Language Support
ReproKit provides thin-client SDKs for Go, Python, and Rust. Each SDK captures error context and writes JSON files that the CLI can import.
Go
import reprokit "github.com/OmkarKirpan/reprokit-go"
rk := reprokit.NewReproKit(reprokit.Config{Debug: true})
// In your error handler:
rk.CaptureError(req.Method, req.URL.Path, 500, reqHeaders, resHeaders, reqBody, resBody, err)Framework examples: Gin, Echo, net/http — see sdks/go/examples/.
Python
pip install reprokit # or add to requirements.txtFastAPI:
from reprokit.fastapi_middleware import ReproKitMiddleware
app.add_middleware(ReproKitMiddleware)Django:
# settings.py
MIDDLEWARE = [..., "reprokit.django_middleware.ReproKitMiddleware"]Flask:
from reprokit.flask_middleware import ReproKit
ReproKit(app)Rust
# Cargo.toml
[dependencies]
reprokit = { version = "0.1", features = ["axum"] }Framework support via feature flags: actix, axum, rocket — see sdks/rust/README.md.
Importing Captures
All SDKs write JSON files to .reprokit/captures/. Import them into the CLI:
reprokit import .reprokit/captures/ # bulk import directory
reprokit import capture.json # single fileHow It Works
Express App
│
├── Your routes throw an error
│
├── ReproKit error middleware captures:
│ request + response + error + environment
│
├── Sanitizes sensitive data
│
├── Deduplicates by stack trace fingerprint
│
└── Writes to local SQLite
│
└── CLI reads and formats for debugging- Zero latency on the happy path (error middleware only fires on errors)
- Synchronous SQLite writes (errors are rare, sub-millisecond)
- All capture logic wrapped in try/catch (never crashes your app)
Requirements
- Node.js >= 18
- Express 4.x or 5.x
License
MIT
