<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ali Abdiyev</title>
    <description>The latest articles on DEV Community by Ali Abdiyev (@abdiev003).</description>
    <link>https://dev.to/abdiev003</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F811528%2F1875fd79-8134-47ee-8168-3eb12a549721.png</url>
      <title>DEV Community: Ali Abdiyev</title>
      <link>https://dev.to/abdiev003</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abdiev003"/>
    <language>en</language>
    <item>
      <title>I built ReqScope — a local API request tracer for Express, because logs weren't enough</title>
      <dc:creator>Ali Abdiyev</dc:creator>
      <pubDate>Tue, 28 Apr 2026 22:39:52 +0000</pubDate>
      <link>https://dev.to/abdiev003/i-built-reqscope-a-local-api-request-tracer-for-express-because-logs-werent-enough-3nep</link>
      <guid>https://dev.to/abdiev003/i-built-reqscope-a-local-api-request-tracer-for-express-because-logs-werent-enough-3nep</guid>
      <description>&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6iqghx6jvu6gbgbi2thh.png" alt="A small open-source tool that shows you what actually happened inside your Express request — slow steps, failures, request/response previews — without spinning up Datadog locally"&gt;
&lt;/h2&gt;

&lt;p&gt;A few weeks ago I was debugging a &lt;code&gt;POST /login&lt;/code&gt; endpoint that was occasionally taking 800ms instead of the usual 120ms. The logs told me nothing useful:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;[INFO] POST /login 200 837ms
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cool. Thanks. Which part was slow?&lt;/p&gt;

&lt;p&gt;I added some &lt;code&gt;console.time()&lt;/code&gt; calls. Found the slow step. Removed them. Two days later, a different endpoint had the same problem. I added the same &lt;code&gt;console.time()&lt;/code&gt; calls again. Removed them again.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;&lt;a href="https://github.com/Abdiev003/reqscope" rel="noopener noreferrer"&gt;ReqScope&lt;/a&gt;&lt;/strong&gt; — a small local API request tracer for Node.js and Express.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it actually does
&lt;/h2&gt;

&lt;p&gt;You wrap the parts of your handler you care about with &lt;code&gt;traceStep&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;reqscope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;traceStep&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@abdiev003/reqscope&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;reqscope&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;traceStep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;findUserByEmail&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findUnique&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;traceStep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;createAccessToken&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="nf"&gt;createToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then ReqScope shows you what actually happened inside the request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /login 182ms

  findUserByEmail      140ms
  createAccessToken     40ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When something is slow or fails, you can immediately see &lt;em&gt;which step&lt;/em&gt; was slow or failed — not just the total request duration.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I wanted out of it
&lt;/h2&gt;

&lt;p&gt;I had a short list of things that bother me when debugging APIs locally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I want to see request and response bodies without piping &lt;code&gt;req.body&lt;/code&gt; to &lt;code&gt;console.log&lt;/code&gt; everywhere.&lt;/li&gt;
&lt;li&gt;I want to see request and response headers when CORS or auth is acting weird.&lt;/li&gt;
&lt;li&gt;I want to reproduce a failing request as &lt;code&gt;curl&lt;/code&gt; so I can share it with a teammate.&lt;/li&gt;
&lt;li&gt;I want sensitive fields (&lt;code&gt;password&lt;/code&gt;, &lt;code&gt;token&lt;/code&gt;, &lt;code&gt;authorization&lt;/code&gt;) redacted by default so I can paste output into Slack without panicking.&lt;/li&gt;
&lt;li&gt;I do &lt;strong&gt;not&lt;/strong&gt; 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.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What about production?
&lt;/h2&gt;

&lt;p&gt;It's off in production by default (&lt;code&gt;enabled: process.env.NODE_ENV !== "production"&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;ReqScope is a &lt;strong&gt;local development tool&lt;/strong&gt;, 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's there today
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Express middleware&lt;/li&gt;
&lt;li&gt;Manual step tracing with &lt;code&gt;traceStep&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Slow request and slow step thresholds (configurable)&lt;/li&gt;
&lt;li&gt;Request/response body and header previews&lt;/li&gt;
&lt;li&gt;Sensitive field masking&lt;/li&gt;
&lt;li&gt;cURL reproduction of any captured request&lt;/li&gt;
&lt;li&gt;A local dashboard (currently runs from the repo during MVP)&lt;/li&gt;
&lt;li&gt;Endpoint summaries
## What's not there yet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm being honest about the MVP status:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No NestJS / Fastify / Koa adapter yet&lt;/li&gt;
&lt;li&gt;No automatic ORM tracing (Prisma, TypeORM) — you wrap calls manually for now&lt;/li&gt;
&lt;li&gt;No persistent storage (traces live in memory, capped at 100 by default)&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i @abdiev003/reqscope
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/@abdiev003/reqscope" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@abdiev003/reqscope&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/Abdiev003/reqscope" rel="noopener noreferrer"&gt;https://github.com/Abdiev003/reqscope&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;StackBlitz demo: &lt;a href="https://stackblitz.com/github/Abdiev003/reqscope/tree/main/demo" rel="noopener noreferrer"&gt;https://stackblitz.com/github/Abdiev003/reqscope/tree/main/demo&lt;/a&gt;
If you try it, I'd genuinely love feedback — especially on the &lt;code&gt;traceStep&lt;/code&gt; API and what frameworks you'd want to see supported next. Issues, PRs, or just a comment here all work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
