api-tracer-kit
v1.1.0
Published
Trace every API call an app makes, and map, exercise and monitor the endpoints it has.
Maintainers
Readme
api-tracer-kit
Trace every API call an application makes — and map, exercise and watch the endpoints it has.
Two halves that work on their own or together:
- the tracer — a framework-free library that records every
fetch,XMLHttpRequestand axios call, with no change to your API layer and no bundler configuration - the console — a CLI and web UI that reads your source into an endpoint catalog, receives the tracer's traffic, and lets you re-send any call, watch for response-shape drift, and export what it captured
npm install api-tracer-kitQuick start
One command wires it into your app — it detects the framework, writes the module that configures the tracer, and adds the import to your entry file:
npx api-tracer setupOr do it by hand, which is two lines:
import { apiTracer } from 'api-tracer-kit';
apiTracer.init();Either way, that is the whole setup. Every call made afterwards is traced:
await fetch('/api/users');
apiTracer.getTraces();
// [{ id, request: { url, method, headers, params, body },
// response: { status, headers, body },
// timing: { startedAt, completedAt, duration }, status: 'success' }]Nothing happens at import time, so the package is safe to import during SSR, in
a build step, or in a test. init() is the only thing that patches anything.
Using axios? Hand yours over — an axios instance has no global to patch:
apiTracer.useAxios(axios);One call covers the default export and every instance axios.create() makes
afterwards.
Want the console?
npx api-tracer startIt reads your source, finds your endpoints, and opens at
http://localhost:4400. Point the tracer at it with reportTo: true and your
app's own traffic fills it in as you click around.
Configure the tracer in exactly one place.
init()is idempotent — a second call keeps the first one's configuration and warns about what it ignored.
Documentation
| | |
| --- | --- |
| Getting started | install, first trace, seeing them |
| Tracer API | every option, the ApiTrace model, storage, axios, lifecycle |
| The console | CLI, dashboard, replay, drift, coverage, import/export, deployment |
| Configuration | the config file, scanner presets, custom parsers, sign-in flows |
| Frameworks | React, Next.js, Vite, CRA, Node, testing |
| Troubleshooting | when nothing is being recorded |
| Security | redaction, what is stored, what is safe to share |
| Architecture | how it works inside, and why |
Features
Tracing
fetch,XMLHttpRequestand axios, automatically- method, absolute URL, path, parsed query params, headers, request body
- response status, status text, headers and body
- start time, completion time and duration
- HTTP errors, network failures, timeouts and aborts, told apart
FormData,URLSearchParams, JSON, text and binary bodies, each recorded as what it was, so a captured call can be replayed the way it was sent- files in a
FormDatarecorded as<file: scan.pdf, 20418 bytes> - a unique id per call, and no mixing between concurrent requests
- credential redaction in headers and bodies, on by default
- envelope reading, for APIs that answer
200and put the verdict in the body - subscribers, a replaceable storage layer, a capped in-memory store by default
Console
- an endpoint catalog read straight out of your source — nothing hand-maintained
- live recording: your app's traffic lands on the endpoint it belongs to, with the real params, payload and path ids already filled in
- send any endpoint, with a Postman-style tabbed editor and a syntax-highlighted JSON editor
- bulk runs, and a full replay of every captured call, with a plan shown first
- response-shape contracts, so a backend that quietly drops a field is caught
even though it answered
200 - coverage: which endpoints your app has never exercised
- an insight report — coverage, failures, drift, risks, hygiene, auth surface, latency, inventory, trend — as Markdown or JSON
- HAR / cURL / Postman export, HAR / cURL import
{{variables}}, captured from responses and chained between calls
Supported environments
| | |
| --- | --- |
| Browsers | ✅ fetch, XMLHttpRequest, axios |
| Node 18+ | ✅ fetch and axios; XMLHttpRequest skipped when absent |
| React / Next.js / Vite / CRA / webpack | ✅ no plugin, loader, alias or config change |
| SSR and build-time execution | ✅ importing does nothing; init() no-ops without a runtime |
| TypeScript | ✅ types shipped, strict-clean, bundler and node16 resolution |
| Deno / Bun | ⚠️ untested, but the tracer only uses standard globals |
Nothing in the core imports React or axios. Both are optional peer dependencies, used only by the entry points that need them.
Entry points
import { apiTracer } from 'api-tracer-kit'; // the tracer
import { useAxios } from 'api-tracer-kit/axios'; // axios integration
import { useApiTraces } from 'api-tracer-kit/react'; // hooks
import { ApiTracerPanel } from 'api-tracer-kit/ui'; // in-app panelEach is bundled separately with sideEffects: false, so importing the tracer
never pulls in React, and an unused import is dropped entirely.
It will not break your API calls
Removing the tracer changes nothing. Responses are read through
Response.clone() after the original is handed back; streaming responses are
never buffered; request-body streams are never consumed; errors are rethrown
exactly as they arrived; nothing is retried and no request is made twice; XHR is
observed with addEventListener rather than by taking onload; and destroy()
restores every patched global.
The full list is in Tracer API.
Limitations
Worth knowing before you rely on it.
- An axios instance must be handed over. There is no global to patch. In a browser the XHR adapter catches axios anyway; in Node it cannot.
- Request bodies that are streams are never read, because reading one would empty it.
- Files in a
FormDataare described, not captured, so a captured upload cannot be replayed with its file. - Response bodies over
maxBodyBytesare omitted, not truncated — a partial JSON body is more misleading than none. Response.clone()buffers. For a large non-streaming response the clone holds a second copy until it is read. The size cap keeps this bounded.- The scanner is regex-based. It reads three common shapes well and says what it could not read; it does not understand a URL assembled from three variables. Live recording covers the rest.
- The "unused endpoint" count is a substring count, so
import * as serviceswould hide a real usage. Confirm with a grep before deleting. - The console is single-user by design: one token, one environment, one set of results.
- Redaction is name-based. A field called
notescontaining personal data is not a credential and is not touched. See Security.
Development
npm install
npm run build # tsup -> dist/, ESM + CJS + .d.ts
npm test # the tracer suite, then the console suite
npm run typecheckThe example project doubles as an end-to-end check:
cd examples/basic && npm install && npm startSee CONTRIBUTING.md.
Licence
MIT
