<?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: xabierlameiro.com</title>
    <description>The latest articles on DEV Community by xabierlameiro.com (@xabierlameiro).</description>
    <link>https://dev.to/xabierlameiro</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1011356%2F478e63c7-639e-4917-9df5-3768dbc8c96c.jpeg</url>
      <title>DEV Community: xabierlameiro.com</title>
      <link>https://dev.to/xabierlameiro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xabierlameiro"/>
    <language>en</language>
    <item>
      <title>How to measure a Next.js memory leak and prove the diagnosis</title>
      <dc:creator>xabierlameiro.com</dc:creator>
      <pubDate>Sat, 05 Sep 2026 13:32:25 +0000</pubDate>
      <link>https://dev.to/xabierlameiro/how-to-measure-a-nextjs-memory-leak-and-prove-the-diagnosis-59bg</link>
      <guid>https://dev.to/xabierlameiro/how-to-measure-a-nextjs-memory-leak-and-prove-the-diagnosis-59bg</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://xabierlameiro.com/blog/nextjs/measure-nextjs-memory-leak" rel="noopener noreferrer"&gt;xabierlameiro.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick answer
&lt;/h2&gt;

&lt;p&gt;Most memory leak reports die in the same place. Someone posts a graph that climbs, a maintainer asks for heap snapshots taken after a forced GC, and nobody comes back. I don't think that's laziness — taking those snapshots &lt;em&gt;correctly&lt;/em&gt; is harder than the thread makes it sound, and getting it wrong gives you numbers that look convincing and mean nothing.&lt;/p&gt;

&lt;p&gt;So I took one open issue and did it properly: &lt;a href="https://github.com/vercel/next.js/issues/95094" rel="noopener noreferrer"&gt;vercel/next.js#95094&lt;/a&gt;, &lt;em&gt;"Memory leak from retained sandbox timeouts causes stepwise heap growth"&lt;/em&gt;. The claim is that &lt;code&gt;setTimeout&lt;/code&gt; inside middleware leaks, because the sandbox keeps every timeout id and never lets go. (Both that issue and #94890 below are now fixed, and shipped in Next.js 16.3.0 — days after this went out. The method is the point here, not the ticket status.)&lt;/p&gt;

&lt;p&gt;That claim is easy to believe and easy to get wrong. Stepwise growth is also what JIT warm-up and lazy caches look like. Telling those two apart is the whole job.&lt;/p&gt;

&lt;p&gt;This post is about the &lt;em&gt;method&lt;/em&gt; — how to measure, and how to prove the diagnosis. If what you actually need is to work out which of the open leaks you're hitting in production, read &lt;a href="https://xabierlameiro.com/blog/nextjs/nextjs-memory-leak-in-production" rel="noopener noreferrer"&gt;how to find a Next.js memory leak in production&lt;/a&gt; first and come back here to confirm it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The protocol matters more than the tool
&lt;/h2&gt;

&lt;p&gt;Every step here exists to kill one specific way of fooling yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A fresh process per route.&lt;/strong&gt; Nothing carries over from the last thing you ran.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Warm-up before the baseline.&lt;/strong&gt; The first requests trigger JIT and lazy caches. Snapshot cold and you bill all of that to the leak.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forced GC — three passes — before every sample.&lt;/strong&gt; Heap the GC can reclaim isn't leaked. Sample without forcing it and you're measuring garbage. This needs the process started with &lt;code&gt;--expose-gc&lt;/code&gt; so &lt;code&gt;global.gc()&lt;/code&gt; is callable, and the snapshot written with &lt;code&gt;v8.writeHeapSnapshot()&lt;/code&gt; right after.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cycles, not a single reading.&lt;/strong&gt; One number tells you nothing. A series has a shape, and the shape is what survives noise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An audit of the load itself.&lt;/strong&gt; A run that quietly failed to send its traffic looks exactly like a healthy route.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last one isn't theoretical. Twice, my own load generator sent almost nothing — once because the timeout was expressed in whole seconds, once because 86% of the requests never finished connecting. Both would have printed a confident &lt;code&gt;stable&lt;/code&gt;. I only caught them because the run records what it actually did.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers
&lt;/h2&gt;

&lt;p&gt;Against the issue's own reproduction repo — next &lt;code&gt;16.3.0-canary.50&lt;/code&gt;, Node 24.15, darwin arm64, 8 cycles of 3000 requests, 20 connections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;heap after forced GC, per cycle (MB):
28.7 → 40.2 → 59.0 → 75.8 → 75.8 → 101.0 → 101.1 → 138.9 → 138.9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the stepwise shape from the title, about &lt;strong&gt;4.7 MB per 1000 requests&lt;/strong&gt;, and it never comes back. Warm-up flattens after a cycle or two. This gives back nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The snapshot diff names the mechanism
&lt;/h2&gt;

&lt;p&gt;A climbing heap tells you that you have a problem. It doesn't tell you what's holding the memory. The diff between the baseline and the final snapshot does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;grown [object] Array  112.47 MB
  — TimeoutsManager#object[.resources]
  &amp;lt;- system / Context#object[.timeoutsManager]
  &amp;lt;- webSetTimeoutPolyfill#closure[.context]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read it upwards: the sandbox's &lt;code&gt;setTimeout&lt;/code&gt; polyfill holds a context, the context holds a &lt;code&gt;TimeoutsManager&lt;/code&gt;, and its &lt;code&gt;resources&lt;/code&gt; array has grown to 112 MB of timeout entries. That's exactly the mechanism the issue describes — and I didn't have to know where to look to find it.&lt;/p&gt;

&lt;p&gt;This is the same thing you'd read by hand in Chrome DevTools: load both snapshots in the Memory tab, switch to the &lt;strong&gt;Comparison&lt;/strong&gt; view, and open the &lt;em&gt;retainers&lt;/em&gt; of whatever grew. The snapshots are kept precisely so you can go and check it yourself — a verdict you can't audit is just an opinion with numbers attached.&lt;/p&gt;

&lt;h2&gt;
  
  
  Removing the cause removes the effect
&lt;/h2&gt;

&lt;p&gt;This is the step people skip, and it's the only one that turns a measurement into a confirmation.&lt;/p&gt;

&lt;p&gt;The thread suggests a workaround: call &lt;code&gt;clearTimeout(id)&lt;/code&gt; inside the callback so the sandbox releases the entry. If my diagnosis is right, that should erase the curve. Same app, same parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;27.8 → 25.2 → 25.3 → 25.4 → 25.4 → 25.5 → 25.5 → 25.5 → 25.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Flat. &lt;strong&gt;+0.02 MB per 1000 requests.&lt;/strong&gt; Nothing changed except the cause, and the effect went with it. That's the standard I'd want from anyone showing me a leak.&lt;/p&gt;

&lt;p&gt;One thing I didn't expect: at 100 concurrent connections, the &lt;em&gt;fixed&lt;/em&gt; version timed out on about 9% of requests. Tracking 500 timeouts per request costs CPU as well as memory, so on hot middleware this matters beyond the heap.&lt;/p&gt;

&lt;p&gt;The full write-up with the reproduction parameters is &lt;a href="https://github.com/vercel/next.js/issues/95094#issuecomment-5035131691" rel="noopener noreferrer"&gt;on the issue itself&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The same method says "no" just as often
&lt;/h2&gt;

&lt;p&gt;I ran this against six open issues. Two more reproduced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/vercel/next.js/issues/94890" rel="noopener noreferrer"&gt;#94890&lt;/a&gt;&lt;/strong&gt; — the router LRU cache doesn't count its keys. Heap 26.7 → 71.9 MB, with the chain pointing into the route filesystem checker. The original report needed 1.2M requests and a custom script; this took 120000 and one command.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/vercel/next.js/issues/84884" rel="noopener noreferrer"&gt;#84884&lt;/a&gt;&lt;/strong&gt; — axios with &lt;code&gt;AbortSignal&lt;/code&gt; in middleware. Four nearly identical routes in the repro, and only &lt;code&gt;/middleware/axios&lt;/code&gt; leaks: 32.8 → 369.9 MB while the other three stay flat. That's isolation by comparison, not a correlation you have to trust.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Three didn't reproduce — and the reasons were in the threads all along. One was fixed upstream in 16.0.3. One is a Node bug the reporter confirmed is gone in Node 26. One is a dev-server problem, which this method can't see by design.&lt;/p&gt;

&lt;p&gt;A negative result with evidence behind it is worth as much as a confirmation. It's the difference between "I couldn't reproduce it" and "here is what I ran, here is what I saw, here is what I ruled out."&lt;/p&gt;

&lt;p&gt;Across ~25 healthy routes on real production apps — PPR, MDX, Auth.js, Sentry, i18n — it reported no false positives. That number matters more to me than the confirmations. A leak detector that cries wolf is worse than not having one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just use Chrome DevTools or memlab?
&lt;/h2&gt;

&lt;p&gt;Because none of them run the experiment for you, and the experiment is the hard part:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;What it gives you&lt;/th&gt;
&lt;th&gt;Where it stops&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Chrome DevTools&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The ground truth: two snapshots and a Comparison view&lt;/td&gt;
&lt;td&gt;You reproduce the load, force the GC, pick the moments and read the retainers yourself. Doing that &lt;em&gt;correctly&lt;/em&gt; is the whole difficulty&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;a href="https://github.com/facebook/memlab" rel="noopener noreferrer"&gt;memlab&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;An excellent heap-analysis engine — I use it to parse the snapshots&lt;/td&gt;
&lt;td&gt;It's built around browser scenarios you script. It doesn't drive HTTP load against your routes, and it knows nothing about Next.js route manifests or your build's source maps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;a href="https://github.com/clinicjs/node-clinic" rel="noopener noreferrer"&gt;clinic.js&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Broad Node performance profiling&lt;/td&gt;
&lt;td&gt;Its own README says it is no longer actively maintained&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;--inspect&lt;/code&gt; + manual snapshots&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full control&lt;/td&gt;
&lt;td&gt;Same as DevTools, plus keeping the process, the load and the snapshots in sync by hand&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;What's missing from all of them isn't the analysis — it's the controlled experiment around it: a fresh process per route, warm-up before the baseline, forced GC and an adaptive idle before every sample, and an audit of whether the load you think you sent actually landed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measuring your own app
&lt;/h2&gt;

&lt;p&gt;I automated the protocol above into a CLI, &lt;a href="https://github.com/xabierlameiro/next-leak" rel="noopener noreferrer"&gt;next-leak&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx next-leak &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It needs App Router, &lt;code&gt;output: "standalone"&lt;/code&gt; and Node ≥ 22. That's a narrow scope on purpose — it's why the false positive count is what it is. You get one of three answers, and all of them are useful: you don't have a leak (the common case, and the report proves it), the leak is yours or a dependency's (named down to the file when the sourcemaps allow it), or it's framework internals, with a draft issue and the snapshots to back it.&lt;/p&gt;

&lt;p&gt;If you're coming at this from the other end — a graph climbing in production and no idea why — start here instead: &lt;a href="https://xabierlameiro.com/blog/nextjs/nextjs-memory-leak-in-production" rel="noopener noreferrer"&gt;How to find a Next.js memory leak in production&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>node</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to find a Next.js memory leak in production</title>
      <dc:creator>xabierlameiro.com</dc:creator>
      <pubDate>Sat, 18 Jul 2026 01:58:24 +0000</pubDate>
      <link>https://dev.to/xabierlameiro/how-to-find-a-nextjs-memory-leak-in-production-2cjd</link>
      <guid>https://dev.to/xabierlameiro/how-to-find-a-nextjs-memory-leak-in-production-2cjd</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://xabierlameiro.com/blog/nextjs/nextjs-memory-leak-in-production" rel="noopener noreferrer"&gt;xabierlameiro.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If your self-hosted Next.js server grows until it dies with &lt;code&gt;FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory&lt;/code&gt; - or the container gets &lt;code&gt;OOMKilled&lt;/code&gt; (exit code 137) - don't start by auditing your own code. As of July 2026 there are three documented memory leaks &lt;strong&gt;open in the framework itself&lt;/strong&gt;, spanning Next.js 15.5 to 16.3.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leak 1: the router LRU cache doesn't count its keys
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/vercel/next.js/issues/94890" rel="noopener noreferrer"&gt;#94890&lt;/a&gt; - the route-resolution cache's size function adds up the value strings but never the URL key, so it can retain ~1M keys (hundreds of MB) while believing it is tiny. Signature: slow heap drift over days that tracks &lt;strong&gt;unique URLs served&lt;/strong&gt; (bot crawls, long slugs), not request volume; heap-snapshot retainer traces end at &lt;code&gt;LRUNode&lt;/code&gt;. Tip: chart your heap against distinct routes, not requests per second.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leak 2: the RSC render tree is retained on client aborts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/vercel/next.js/issues/94919" rel="noopener noreferrer"&gt;#94919&lt;/a&gt; - streams that don't finish normally (mobile clients, crawlers, users navigating away) pin the whole element tree via the Flight request's AbortController. Much stronger on Node 22/24 than 20; the reporter measured ~2 MB per request on heavy pages. Mitigation while it stays open: trim the RSC payload of your heaviest pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leak 3: middleware setTimeout ids retained by the sandbox
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/vercel/next.js/issues/95094" rel="noopener noreferrer"&gt;#95094&lt;/a&gt; - the sandbox TimeoutsManager only releases a timeout id on explicit &lt;code&gt;clearTimeout&lt;/code&gt;. A one-line workaround that works today:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timeoutId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&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="nf"&gt;fireAndForgetWork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeoutId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// releases the id from the sandbox manager&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Which one are you hitting?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Growth shape&lt;/th&gt;
&lt;th&gt;Correlates with&lt;/th&gt;
&lt;th&gt;Suspect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Slow, monotonic drift over days&lt;/td&gt;
&lt;td&gt;Unique URLs (bots, long slugs)&lt;/td&gt;
&lt;td&gt;Router LRU cache (#94890)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Proportional to traffic; worse on heavy pages&lt;/td&gt;
&lt;td&gt;RSC payload and client aborts&lt;/td&gt;
&lt;td&gt;RSC tree retention (#94919)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Steps the GC never recovers&lt;/td&gt;
&lt;td&gt;Requests through middleware&lt;/td&gt;
&lt;td&gt;Sandbox timeouts (#95094)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No OOM, but sporadic 504s on serverless&lt;/td&gt;
&lt;td&gt;Render cost, not memory&lt;/td&gt;
&lt;td&gt;Your render is expensive&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;To confirm: start with &lt;code&gt;NODE_OPTIONS='--inspect' next start&lt;/code&gt;, take two heap snapshots separated by load, and read the retainers in Chrome DevTools' Memory tab.&lt;/p&gt;

&lt;h2&gt;
  
  
  On serverless the leak wears a disguise
&lt;/h2&gt;

&lt;p&gt;You don't get the OOM - you get 504s. My blog's tag pages were timing out with &lt;code&gt;FUNCTION_INVOCATION_TIMEOUT&lt;/code&gt; because of an O(N^2) post loader (a ~32-second render against a ~10-second limit); instance recycling had been hiding the waste. The fix was a module-level cache: memory spent on purpose, bounded and static per deploy.&lt;/p&gt;

&lt;p&gt;The full diagnosis flow - which retainer maps to which issue, the exact docs commands, and my 504 postmortem with before/after numbers - is in the original post: &lt;a href="https://xabierlameiro.com/blog/nextjs/nextjs-memory-leak-in-production" rel="noopener noreferrer"&gt;https://xabierlameiro.com/blog/nextjs/nextjs-memory-leak-in-production&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update (Jul 21):&lt;/strong&gt; I automated this diagnosis flow into a CLI: &lt;a href="https://github.com/xabierlameiro/next-leak" rel="noopener noreferrer"&gt;next-leak&lt;/a&gt; - &lt;code&gt;npx next-leak . --quick&lt;/code&gt; runs the whole ritual (fresh process per route, forced GC before each sample, verdict from the curve shape) and names the retaining objects. It confirmed #95094 and #94890 on its own. MIT, source on GitHub, and the full write-up is in the &lt;a href="https://xabierlameiro.com/blog/nextjs/nextjs-memory-leak-in-production" rel="noopener noreferrer"&gt;original post&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>node</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How document my react components with JSDoc</title>
      <dc:creator>xabierlameiro.com</dc:creator>
      <pubDate>Thu, 19 Jan 2023 18:55:44 +0000</pubDate>
      <link>https://dev.to/xabierlameiro/how-document-my-react-components-with-jsdoc-2gnk</link>
      <guid>https://dev.to/xabierlameiro/how-document-my-react-components-with-jsdoc-2gnk</guid>
      <description>&lt;p&gt;It is necessary to have a good documentation about our components, so that other developers can understand how it works and how to use it. In this article we are going to see how we can document our react components with JSDoc and how to publish the documentation in our static site.&lt;/p&gt;

&lt;p&gt;With a few simple steps, the jsdoc library and the use of good programming practices when working with react, we will be able to have a documentation of our components automatically. There are different plugins to upgrade our jsdoc and support react, but as React is still javascript and the components functions the default lib is more than enough.&lt;/p&gt;

&lt;p&gt;The report we are going to generate is still an html file, so you can deploy it in any static site&lt;/p&gt;

&lt;p&gt;More details here : &lt;a href="https://xabierlameiro.com/blog/react/how-document-my-react-components-with-jsdoc"&gt;How document my react components with JSDoc&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>jsdoc</category>
      <category>nextjs</category>
    </item>
  </channel>
</rss>
