<?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: Giu</title>
    <description>The latest articles on DEV Community by Giu (@pfgiiu).</description>
    <link>https://dev.to/pfgiiu</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%2F4082387%2F8145a7de-d31d-49d9-9b35-9b31be354127.png</url>
      <title>DEV Community: Giu</title>
      <link>https://dev.to/pfgiiu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pfgiiu"/>
    <language>en</language>
    <item>
      <title>Next.js 16.3's Memory Claim Didn't Hold Up on My App. Its TypeScript Claim Cut My Build by Two Thirds.</title>
      <dc:creator>Giu</dc:creator>
      <pubDate>Wed, 19 Aug 2026 00:50:23 +0000</pubDate>
      <link>https://dev.to/pfgiiu/nextjs-163s-memory-claim-didnt-hold-up-on-my-app-its-typescript-claim-cut-my-build-by-two-30om</link>
      <guid>https://dev.to/pfgiiu/nextjs-163s-memory-claim-didnt-hold-up-on-my-app-its-typescript-claim-cut-my-build-by-two-30om</guid>
      <description>&lt;h2&gt;
  
  
  The claim
&lt;/h2&gt;

&lt;p&gt;Next.js 16.3 shipped on August 3, 2026, and the headline number is memory: long&lt;br&gt;
development sessions, Vercel says, now use up to 90% less RAM. The release notes&lt;br&gt;
list more than that — repeat builds that read unchanged artifacts straight from&lt;br&gt;
cache, type checking that can hand off to TypeScript 7, a server handling&lt;br&gt;
roughly 22% more requests under load, and a new set of navigation primitives&lt;br&gt;
called Instant Navigations.&lt;/p&gt;

&lt;p&gt;Anyone who's watched a dev server climb until Node gives up and prints FATAL&lt;br&gt;
ERROR knows why the memory line is the one that matters. It's also the hardest&lt;br&gt;
to verify. "Up to 90%" was measured on Vercel's workloads, not yours, and two&lt;br&gt;
weeks after release nobody had published independent numbers from a real app.&lt;/p&gt;

&lt;p&gt;So I upgraded one. What follows is a single production app taken from 16.2.3 to&lt;br&gt;
16.3.1, every build time and memory reading recorded before and after, same&lt;br&gt;
machine and same procedure on both sides, three runs each.&lt;/p&gt;

&lt;p&gt;The short version: the memory claim didn't survive contact with this app. The&lt;br&gt;
TypeScript claim did, and it turned out to matter far more — it cut two thirds&lt;br&gt;
off the build. The headline number and the useful number weren't the same&lt;br&gt;
number.&lt;/p&gt;

&lt;p&gt;All raw data, the measurement scripts, and the full upgrade log are in the repo: &lt;a href="https://github.com/pfgiiu/artigo01" rel="noopener noreferrer"&gt;https://github.com/pfgiiu/artigo01&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Methodology
&lt;/h2&gt;

&lt;p&gt;The subject is a production Next.js app that builds 142 static pages on the App&lt;br&gt;
Router with Turbopack. Not a scaffolded demo: a scaffold has almost no&lt;br&gt;
dependency graph, and the dependency graph is precisely what eats memory.&lt;/p&gt;

&lt;p&gt;Environment: Windows 11 Pro, Node v24.13.1, npm 11.8.0, TypeScript 5.9.3. The&lt;br&gt;
baseline is Next.js 16.2.3 with React 19.2.4; the target is 16.3.1. Only the&lt;br&gt;
framework version changes between runs.&lt;/p&gt;
&lt;h3&gt;
  
  
  Build time
&lt;/h3&gt;

&lt;p&gt;Each build runs twice with &lt;code&gt;.next&lt;/code&gt; deleted beforehand. The first is cold. The&lt;br&gt;
second follows immediately, with the OS file cache warm and Next.js able to read&lt;br&gt;
unchanged artifacts from its own cache. I report both, because the distance&lt;br&gt;
between them is itself one of the release's claims.&lt;/p&gt;
&lt;h3&gt;
  
  
  Memory
&lt;/h3&gt;

&lt;p&gt;Windows doesn't expose RSS. The equivalent is &lt;code&gt;PeakWorkingSet64&lt;/code&gt;, and since the&lt;br&gt;
dev server runs across three Node processes, every figure below is the sum&lt;br&gt;
across the whole process tree — a single-process reading would quietly throw&lt;br&gt;
away most of the footprint.&lt;/p&gt;

&lt;p&gt;Sampling runs every 10 seconds through a PowerShell script that starts the&lt;br&gt;
server, waits for readiness on port 3000, tracks the process tree, and writes&lt;br&gt;
results to JSON. Before each run the port is confirmed free and no stray Node&lt;br&gt;
processes are alive, so nothing from a previous session inflates the numbers.&lt;/p&gt;

&lt;p&gt;Two scenarios:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario A — Idle.&lt;/strong&gt; &lt;code&gt;npm run dev&lt;/code&gt; started fresh and left alone for ten&lt;br&gt;
minutes with no HTTP requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario B — Active HMR.&lt;/strong&gt; The route compiles once, then a real edit lands in&lt;br&gt;
a mounted, visible component every two minutes for ten minutes — five edits&lt;br&gt;
total — each followed by a GET to force recompilation. The target is the hero&lt;br&gt;
heading in the home page component, chosen because it renders in a mounted&lt;br&gt;
client component, which guarantees Fast Refresh actually fires instead of the&lt;br&gt;
change being discarded. The file is restored with &lt;code&gt;git checkout&lt;/code&gt; afterward, and&lt;br&gt;
every edit is logged verbatim.&lt;/p&gt;

&lt;p&gt;Both scenarios exist because the claim is about long development sessions, not&lt;br&gt;
idle servers. An idle reading alone would understate what the release changes,&lt;br&gt;
and reporting it as though it addressed the claim would be the wrong measurement&lt;br&gt;
dressed up as the right one.&lt;/p&gt;
&lt;h3&gt;
  
  
  TypeScript
&lt;/h3&gt;

&lt;p&gt;The type-check phase is measured separately from compilation, since 16.3 prints&lt;br&gt;
both explicitly. TypeScript 7 is tested on a throwaway branch, with and without&lt;br&gt;
&lt;code&gt;experimental.useTypeScriptCli&lt;/code&gt;, then removed — the shipped tree stays on 5.9.3.&lt;/p&gt;
&lt;h2&gt;
  
  
  Baseline: Next.js 16.2.3
&lt;/h2&gt;

&lt;p&gt;Both baseline builds exit clean, no warnings, and the dev server readied in&lt;br&gt;
1497ms with nothing in the log. That matters for what follows: this isn't a&lt;br&gt;
broken project where any change looks like an improvement.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;16.2.3&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cold build (&lt;code&gt;.next&lt;/code&gt; deleted)&lt;/td&gt;
&lt;td&gt;95.3s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Second build (cache warm)&lt;/td&gt;
&lt;td&gt;63.8s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dev ready&lt;/td&gt;
&lt;td&gt;1497ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Static pages generated&lt;/td&gt;
&lt;td&gt;142&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Peak working set — idle&lt;/td&gt;
&lt;td&gt;355.7 MB (3 processes)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Peak working set — active HMR&lt;/td&gt;
&lt;td&gt;564.8 MB (3 processes)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;An idle dev server turns out to be a near-flat line. A 30-second smoke run of&lt;br&gt;
the same script recorded roughly 351 MB; ten minutes of sitting still brought it&lt;br&gt;
to 355.7 MB — growth of about 1.3%. The server allocates what it needs at&lt;br&gt;
startup and then stops.&lt;/p&gt;

&lt;p&gt;Start editing and the picture changes. Same server, same three processes, same&lt;br&gt;
ten minutes, but with five single-line edits to a mounted component: 564.8 MB.&lt;br&gt;
That's 209 MB of growth, a 59% increase, from five edits.&lt;/p&gt;

&lt;p&gt;Five edits is nothing. A real morning is a few hundred. The baseline doesn't&lt;br&gt;
prove the server would fall over by lunchtime, but it does show where the&lt;br&gt;
accumulation comes from, and it makes the shape of the problem legible. Idle&lt;br&gt;
cost is fixed and modest. Session cost is what climbs. Any honest test of a&lt;br&gt;
memory improvement has to look at the second one.&lt;/p&gt;

&lt;p&gt;That also makes Scenario A a control. If 16.3 barely moves it, the release is&lt;br&gt;
doing its work during the session, not at startup.&lt;/p&gt;

&lt;p&gt;Now the builds. The 33% drop between the two is the expected cache effect, but&lt;br&gt;
the breakdown is more interesting than the total. Compilation falls from 32.8s&lt;br&gt;
to 18.4s — a 44% saving, and clearly where the cache earns its keep. Type&lt;br&gt;
checking barely budges: 40s to 37.5s, under 7%.&lt;/p&gt;

&lt;p&gt;Which means that by the second build, TypeScript accounts for 37.5 of 63.8&lt;br&gt;
seconds. Nearly 60% of the wall-clock time goes to something the build cache&lt;br&gt;
can't touch. Any further improvement to repeat builds has to come from the type&lt;br&gt;
checker, not from caching more artifacts — and that's exactly what 16.3 claims&lt;br&gt;
to address by letting &lt;code&gt;next build&lt;/code&gt; type check with TypeScript 7.&lt;/p&gt;

&lt;p&gt;So the baseline hands us a specific question to test, rather than a vague hope&lt;br&gt;
that the upgrade feels faster.&lt;/p&gt;
&lt;h3&gt;
  
  
  Recompile latency
&lt;/h3&gt;

&lt;p&gt;Worth recording separately, because it contradicted the assumption I started&lt;br&gt;
with. Watching the raw dev log during a run, you see several multi-second&lt;br&gt;
&lt;code&gt;GET / 200&lt;/code&gt; lines that look like slow recompiles. They aren't. They're the&lt;br&gt;
one-time cold compile of the route and its proxy.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;Recompile GET (wall)&lt;/th&gt;
&lt;th&gt;Steady GET&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Initial cold load&lt;/td&gt;
&lt;td&gt;12.1s&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edit 1&lt;/td&gt;
&lt;td&gt;248 ms&lt;/td&gt;
&lt;td&gt;59 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edit 2&lt;/td&gt;
&lt;td&gt;225 ms&lt;/td&gt;
&lt;td&gt;55 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edit 3&lt;/td&gt;
&lt;td&gt;239 ms&lt;/td&gt;
&lt;td&gt;57 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edit 4&lt;/td&gt;
&lt;td&gt;231 ms&lt;/td&gt;
&lt;td&gt;55 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edit 5&lt;/td&gt;
&lt;td&gt;238 ms&lt;/td&gt;
&lt;td&gt;57 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Median recompile after an edit: 238 ms. Median steady-state request: 57 ms. Fast&lt;br&gt;
Refresh on this app is already quick, which leaves 16.3 very little room here.&lt;/p&gt;

&lt;p&gt;One note, since it affects how you read these figures: Next.js logs route&lt;br&gt;
compilation on a separate line from the request, so the &lt;code&gt;GET ... in Xms&lt;/code&gt; number&lt;br&gt;
can undercount badly. The cold load took 12.1s of wall-clock time while its&lt;br&gt;
dev-log line reported 827 ms. Wall-clock is the honest number, and that's what&lt;br&gt;
the table uses.&lt;/p&gt;
&lt;h2&gt;
  
  
  The upgrade
&lt;/h2&gt;

&lt;p&gt;The upgrade itself was a non-event.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-exact&lt;/span&gt; next@16.3.1 eslint-config-next@16.3.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two cold builds afterward, both exit 0, no warnings, no type errors, 142 static&lt;br&gt;
pages — same as before. No codemod, no API changes, nothing in the app touched.&lt;br&gt;
On a 142-page production codebase, the framework upgrade was one command.&lt;br&gt;
(&lt;code&gt;npm audit&lt;/code&gt; reports seven pre-existing vulnerabilities, unchanged by the bump&lt;br&gt;
and out of scope here.)&lt;/p&gt;

&lt;p&gt;One side effect will show up in your &lt;code&gt;git status&lt;/code&gt; and look like something went&lt;br&gt;
wrong. It isn't. It's a feature, and an odd one.&lt;/p&gt;
&lt;h3&gt;
  
  
  Next.js now writes instructions to your AI agents
&lt;/h3&gt;

&lt;p&gt;Running &lt;code&gt;next dev&lt;/code&gt; on 16.3.x regenerates a &lt;code&gt;nextjs-agent-rules&lt;/code&gt; block in&lt;br&gt;
&lt;code&gt;AGENTS.md&lt;/code&gt; at your repo root, from Next's own &lt;code&gt;generate-agent-files.js&lt;/code&gt;. The&lt;br&gt;
release notes call this "versioned docs for AI agents." In practice it's a short&lt;br&gt;
message aimed past you, at whatever coding assistant reads the repo. It opens by&lt;br&gt;
telling the agent that this isn't the Next.js it knows, that its training data&lt;br&gt;
may be stale, and that it should read the version-matched docs bundled at&lt;br&gt;
&lt;code&gt;node_modules/next/dist/docs/&lt;/code&gt; before writing any code.&lt;/p&gt;

&lt;p&gt;That's a reasonable answer to a real problem. Any model trained before August&lt;br&gt;
2026 has a confidently wrong picture of this release, and pointing it at docs&lt;br&gt;
that ship with the installed version beats hoping it guesses well.&lt;/p&gt;

&lt;p&gt;Practical note: the block regenerates on every &lt;code&gt;next dev&lt;/code&gt;, so reverting it just&lt;br&gt;
recreates the change. Commit it with the upgrade.&lt;/p&gt;

&lt;p&gt;I'd flag one thing the block doesn't. A generated file that tells your tooling&lt;br&gt;
how to behave is worth reading yourself, rather than committing on the strength&lt;br&gt;
of its own explanation. Here the claim checks out against&lt;br&gt;
&lt;code&gt;generate-agent-files.js&lt;/code&gt; in the installed package — but that's the sort of&lt;br&gt;
thing to verify rather than assume, especially as more frameworks start writing&lt;br&gt;
into agent-readable files.&lt;/p&gt;
&lt;h2&gt;
  
  
  What actually broke
&lt;/h2&gt;

&lt;p&gt;Nothing broke. Zero errors, zero warnings, zero required code changes.&lt;/p&gt;

&lt;p&gt;That's a real result for a minor release, and I'd rather report it than pad this&lt;br&gt;
section. It's also worth being precise about what it does and doesn't tell you.&lt;br&gt;
This app has no custom webpack config, doesn't run &lt;code&gt;middleware&lt;/code&gt;/&lt;code&gt;proxy&lt;/code&gt; with&lt;br&gt;
complex matchers, and doesn't lean on the &lt;code&gt;next/image&lt;/code&gt; defaults in unusual ways.&lt;br&gt;
A codebase that does may have a rougher time. What this run establishes is that&lt;br&gt;
a straightforward production app upgrades cleanly — not that every app will.&lt;/p&gt;
&lt;h2&gt;
  
  
  Results: memory
&lt;/h2&gt;

&lt;p&gt;Every scenario ran three times on each version, with the machine verified clean&lt;br&gt;
before each of the twelve runs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Idle — peak working set, MB&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Version&lt;/th&gt;
&lt;th&gt;Run 1&lt;/th&gt;
&lt;th&gt;Run 2&lt;/th&gt;
&lt;th&gt;Run 3&lt;/th&gt;
&lt;th&gt;Median&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;16.2.3&lt;/td&gt;
&lt;td&gt;481.6&lt;/td&gt;
&lt;td&gt;360.1&lt;/td&gt;
&lt;td&gt;357.3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;360.1&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16.3.1&lt;/td&gt;
&lt;td&gt;429.9&lt;/td&gt;
&lt;td&gt;432.8&lt;/td&gt;
&lt;td&gt;439.7&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;432.8&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Active HMR — peak working set, MB&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Version&lt;/th&gt;
&lt;th&gt;Run 1&lt;/th&gt;
&lt;th&gt;Run 2&lt;/th&gt;
&lt;th&gt;Run 3&lt;/th&gt;
&lt;th&gt;Median&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;16.2.3&lt;/td&gt;
&lt;td&gt;988.4&lt;/td&gt;
&lt;td&gt;562.4&lt;/td&gt;
&lt;td&gt;567.8&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;567.8&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16.3.1&lt;/td&gt;
&lt;td&gt;867.0&lt;/td&gt;
&lt;td&gt;509.0&lt;/td&gt;
&lt;td&gt;513.4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;513.4&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Read the medians, not the ranges. In three of the four groups, run 1 is a high&lt;br&gt;
outlier, and the cause is known rather than mysterious: clearing &lt;code&gt;.next&lt;/code&gt; between&lt;br&gt;
phases failed on a locked &lt;code&gt;pdf-parse&lt;/code&gt; temp directory, so the first run after&lt;br&gt;
each version switch was working against a cache left by the other version. Runs&lt;br&gt;
two and three land within 3–7 MB of each other, and the two versions' warm&lt;br&gt;
clusters don't overlap. The spread is a systematic cold-start effect, not noise.&lt;/p&gt;

&lt;p&gt;That gives two findings pointing in opposite directions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Idle got worse: 360 MB to 433 MB, about 20% more.&lt;/strong&gt; A dev server left running&lt;br&gt;
with no requests costs more memory on 16.3.1 than on 16.2.3.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Active HMR got better: 568 MB to 513 MB, about 10% less.&lt;/strong&gt; Under an actual&lt;br&gt;
editing session, the direction flips.&lt;/p&gt;

&lt;p&gt;The flip fits what the release targets — long development sessions, not idle&lt;br&gt;
servers — and it justifies measuring both. An idle-only benchmark would have&lt;br&gt;
concluded the release was a straight regression. An idle-only benchmark is also&lt;br&gt;
what most people would have run.&lt;/p&gt;

&lt;p&gt;But 10% isn't 90%. Vercel's "up to" is doing real work in that sentence.&lt;br&gt;
Whatever workload produces a 90% reduction, it isn't a 142-page App Router app&lt;br&gt;
edited five times over ten minutes on a Windows laptop. On this app the memory&lt;br&gt;
change is small enough that you'd never notice it, and it arrives bundled with&lt;br&gt;
an idle regression you'd never notice either.&lt;/p&gt;
&lt;h2&gt;
  
  
  Results: TypeScript 7
&lt;/h2&gt;

&lt;p&gt;This is where the release earns its keep, and the baseline told us in advance&lt;br&gt;
where to look. Type checking was 37.5 of 63.8 seconds on a warm build — the part&lt;br&gt;
no amount of caching could reach.&lt;/p&gt;

&lt;p&gt;Getting TypeScript 7 takes one command. It went GA in July 2026 and now ships as&lt;br&gt;
the standard &lt;code&gt;typescript&lt;/code&gt; package, and since Next resolves the checker from that&lt;br&gt;
package, bumping it is the whole migration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; typescript@7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The type-check phase, across four cold builds:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Build&lt;/th&gt;
&lt;th&gt;Compile&lt;/th&gt;
&lt;th&gt;TypeScript&lt;/th&gt;
&lt;th&gt;Errors&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;tsc 5.9.3 (16.2.3)&lt;/td&gt;
&lt;td&gt;#2&lt;/td&gt;
&lt;td&gt;18.4s&lt;/td&gt;
&lt;td&gt;37.5s&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tsc 5.9.3 (16.3.1)&lt;/td&gt;
&lt;td&gt;#2&lt;/td&gt;
&lt;td&gt;19.7s&lt;/td&gt;
&lt;td&gt;29.3s&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TS7, default&lt;/td&gt;
&lt;td&gt;#1 / #2&lt;/td&gt;
&lt;td&gt;23.2s / 13.2s&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4.3s / 4.4s&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TS7, &lt;code&gt;useTypeScriptCli: true&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;#1 / #2&lt;/td&gt;
&lt;td&gt;19.4s / 11.3s&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3.0s / 3.8s&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Roughly 33 seconds down to roughly 3.5. About eight times faster, and it holds&lt;br&gt;
across every run. Turbopack compilation is unaffected — this is entirely the&lt;br&gt;
type checker.&lt;/p&gt;

&lt;p&gt;On total wall-clock, the warm build went from 63.8s on 16.2.3 to 21.2s on 16.3.1&lt;br&gt;
with TS7 and the CLI flag. Two thirds of the build, gone, from a framework bump&lt;br&gt;
and a dependency bump.&lt;/p&gt;

&lt;p&gt;Two caveats matter more than the number.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zero errors is a property of this project, not of TypeScript 7.&lt;/strong&gt; This&lt;br&gt;
codebase already sets &lt;code&gt;strict: true&lt;/code&gt;, so TS7's stricter defaults surfaced&lt;br&gt;
nothing new — a standalone &lt;code&gt;tsc --noEmit&lt;/code&gt; across 270 files exited clean. A&lt;br&gt;
codebase that isn't already strict should expect the opposite, and should budget&lt;br&gt;
for cleanup rather than for a free eight-fold speedup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The flag matters less than the docs imply.&lt;/strong&gt; TypeScript 7 ships no JS compiler&lt;br&gt;
API — &lt;code&gt;lib/typescript.js&lt;/code&gt; is simply absent, leaving only the native binary&lt;br&gt;
launchers. Reading Next's source, I expected the default &lt;code&gt;typescript-api&lt;/code&gt; mode&lt;br&gt;
to fail with &lt;code&gt;E1467&lt;/code&gt;. It didn't: Next fell back to the TS7 CLI and built clean&lt;br&gt;
without the flag. Setting &lt;code&gt;experimental.useTypeScriptCli: true&lt;/code&gt; is marginally&lt;br&gt;
faster, around 3s versus 4s, but it isn't the difference between working and not&lt;br&gt;
working. I'm reporting this because my source-based prediction was wrong, and&lt;br&gt;
the empirical result is the one that counts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should you upgrade?
&lt;/h2&gt;

&lt;p&gt;Two cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you're still on Next.js 15&lt;/strong&gt;, the timeline decides for you. Version 15&lt;br&gt;
reaches end of support on October 21, 2026 — no more security patches after&lt;br&gt;
that. The 15 to 16 jump is a real major upgrade with breaking changes, including&lt;br&gt;
the removal of synchronous access to &lt;code&gt;params&lt;/code&gt;, &lt;code&gt;searchParams&lt;/code&gt;, &lt;code&gt;cookies()&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;headers()&lt;/code&gt; and &lt;code&gt;draftMode()&lt;/code&gt;. Budget real time for it, and start before the&lt;br&gt;
deadline rather than during it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you're already on 16.1 or 16.2&lt;/strong&gt;, upgrade — but do it for the type checker,&lt;br&gt;
not the memory. The framework bump on its own buys you almost nothing measurable&lt;br&gt;
and costs you nothing either: one command, zero errors, zero code changes. Do it&lt;br&gt;
and move on. Then bump TypeScript to 7 the same afternoon, because that's where&lt;br&gt;
two thirds of your build time is hiding. If your project isn't already strict,&lt;br&gt;
do that part on its own branch and expect to spend real time on the errors it&lt;br&gt;
surfaces. The speedup is worth it, but it isn't free for everyone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproducing this
&lt;/h2&gt;

&lt;p&gt;The measurement scripts, the raw JSON from all twelve runs, the full benchmark&lt;br&gt;
tables and the complete upgrade log are here:&lt;br&gt;
&lt;a href="https://github.com/pfgiiu/artigo01" rel="noopener noreferrer"&gt;https://github.com/pfgiiu/artigo01&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two caveats for anyone repeating this. Clearing &lt;code&gt;.next&lt;/code&gt; between runs has to&lt;br&gt;
actually succeed — a locked temp file silently turned my first run of each group&lt;br&gt;
into a cold-start outlier. And the recompile-latency figures in the raw data&lt;br&gt;
aren't comparable across versions, because the baseline was captured cold and&lt;br&gt;
the 16.3.1 run warm. I've left them out of the comparison above for that reason.&lt;/p&gt;

&lt;p&gt;Numbers from a single app on a single machine are one data point, not a&lt;br&gt;
benchmark suite. If you run the same procedure on your own codebase, I'd like to&lt;br&gt;
see what you get.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
