A few weeks ago I was debugging a POST /login endpoint that was occasionally taking 800ms instead of the usual 120ms. The logs told me nothing useful:
[INFO] POST /login 200 837ms
Cool. Thanks. Which part was slow?
I added some console.time() calls. Found the slow step. Removed them. Two days later, a different endpoint had the same problem. I added the same console.time() calls again. Removed them again.
At some point I asked myself why I was doing this manually every time, and why every "real" solution (Datadog, New Relic, OpenTelemetry collectors) felt completely overkill for a local dev environment.
So I built ReqScope — a small local API request tracer for Node.js and Express.
What it actually does
You wrap the parts of your handler you care about with traceStep:
import express from "express";
import { reqscope, traceStep } from "@abdiev003/reqscope";
const app = express();
app.use(express.json());
app.use(reqscope());
app.post("/login", async (req, res, next) => {
try {
const user = await traceStep("findUserByEmail", () =>
db.user.findUnique({ where: { email: req.body.email } })
);
const token = await traceStep("createAccessToken", () =>
createToken(user)
);
res.json({ user, token });
} catch (error) {
next(error);
}
});
And then ReqScope shows you what actually happened inside the request:
POST /login 182ms
findUserByEmail 140ms
createAccessToken 40ms
When something is slow or fails, you can immediately see which step was slow or failed — not just the total request duration.
What I wanted out of it
I had a short list of things that bother me when debugging APIs locally:
- I want to see request and response bodies without piping
req.bodytoconsole.logeverywhere. - I want to see request and response headers when CORS or auth is acting weird.
- I want to reproduce a failing request as
curlso I can share it with a teammate. - I want sensitive fields (
password,token,authorization) redacted by default so I can paste output into Slack without panicking. - I do not want to install an agent, run a Docker container, or sign up for anything. So that's what ReqScope does. Everything stays in memory. The data lives in your process. There is no external service.
What about production?
It's off in production by default (enabled: process.env.NODE_ENV !== "production").
ReqScope is a local development tool, not an APM. If you need distributed tracing across services, OpenTelemetry is the right answer. If you need to monitor production at scale, Datadog or Sentry is the right answer. ReqScope is for the moment when you're sitting at your laptop, something is slow, and you want to know why — without leaving your terminal.
What's there today
- Express middleware
- Manual step tracing with
traceStep - Slow request and slow step thresholds (configurable)
- Request/response body and header previews
- Sensitive field masking
- cURL reproduction of any captured request
- A local dashboard (currently runs from the repo during MVP)
- Endpoint summaries ## What's not there yet
I'm being honest about the MVP status:
- No NestJS / Fastify / Koa adapter yet
- No automatic ORM tracing (Prisma, TypeORM) — you wrap calls manually for now
- No persistent storage (traces live in memory, capped at 100 by default)
- Dashboard is not yet shipped via npm — you clone the repo to run it These are the next things I want to tackle, roughly in that order.
Try it
npm i @abdiev003/reqscope
- npm: https://www.npmjs.com/package/@abdiev003/reqscope
- GitHub: https://github.com/Abdiev003/reqscope
- StackBlitz demo: https://stackblitz.com/github/Abdiev003/reqscope/tree/main/demo
If you try it, I'd genuinely love feedback — especially on the
traceStepAPI and what frameworks you'd want to see supported next. Issues, PRs, or just a comment here all work.
Thanks for reading.