<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[LeoGtz‘s Blog]]></title><description><![CDATA[I write about things i am building, currently learning and what i have learned.]]></description><link>https://blog.leogtz.de</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1593680282896/kNC7E8IR4.png</url><title>LeoGtz‘s Blog</title><link>https://blog.leogtz.de</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 18 May 2026 11:01:25 GMT</lastBuildDate><atom:link href="https://blog.leogtz.de/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[My CLI was slow — then I stopped awaiting everything]]></title><description><![CDATA[I build a CLI that scans a directory full of projects and runs npm audit --json on each one to find vulnerabilities. It worked but it felt slow. Every project waited for the previous one to finish bef]]></description><link>https://blog.leogtz.de/my-cli-was-slow-then-i-stopped-awaiting-everything</link><guid isPermaLink="true">https://blog.leogtz.de/my-cli-was-slow-then-i-stopped-awaiting-everything</guid><category><![CDATA[Node.js]]></category><category><![CDATA[cli]]></category><category><![CDATA[promises]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Leo]]></dc:creator><pubDate>Mon, 18 May 2026 08:52:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/69ca56cb9fffa74740fefc01/71e6df0a-c272-45a6-9175-31effac9a17a.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I build a CLI that scans a directory full of projects and runs npm audit --json on each one to find vulnerabilities. It worked but it felt slow. Every project waited for the previous one to finish before starting.</p>
<p>I was doing something like this (roughly):</p>
<pre><code class="language-typescript">for (const dir of dirs) { 
    await runAudit(dir)
}
</code></pre>
<p>The problem is each npm audit call was waiting for the one before it to finish. All of them could run at the same time, but I was forcing them to run one by one.</p>
<h2>The fix Promise.all</h2>
<p>Instead of awaiting each call inside the loop, I stored all the promises into an array and resolved them all at once:</p>
<pre><code class="language-typescript">const dirs = await fs.readdir(config.path);

for (let dir of dirs) {
  let dirFullPath = `\({config.path}\){dir}`;
  const projectDir = await fs.readdir(dirFullPath);
  if (projectDir.includes("package.json")) {
    projects.push(getAuditPromise(dirFullPath, dir, spinner));
  }
}

projectsOutputs = await Promise.all(projects);
</code></pre>
<p>Now all the npm audit calls kick off at the same time. Way faster, way smoother.</p>
<p>The thing I learned: await inside a loop is usually bad. If the tasks don't depend on each other.</p>
<h2>But then I learned about Promise.allSettled</h2>
<p>After getting this working I realized there's a problem. If one project has a corrupted package.json and npm audit throws, Promise.all cancels everything. You lose results from all the other projects.</p>
<p>Promise.allSettled waits for every promise to finish. Each result tells you whether it succeeded or failed:</p>
<pre><code class="language-typescript">const results = await Promise.allSettled(projects);

for (const result of results) {
  if (result.status === "fulfilled") {
    projectAudits.push(result.value);
  } else {
    spinner.warn(result.reason);
  }
}
</code></pre>
<p>One thing that caught me out. Your promises need to actually reject on failure, otherwise everything shows as fulfilled even when something went wrong. I had my function resolving bad output and allSettled had nothing to catch. Took me a minute to figure out why it wasn't working.</p>
<p>For a vulnerability scanner this is probably more correct. If a project fails I can still show the user which ones succeeded and warn them that a specific project might have a corrupted lock file.</p>
<h2>Thats it</h2>
<p>Have a great Day :)</p>
]]></content:encoded></item></channel></rss>