GeezerVison is showing github.com — feat(build): summarise the client bundle at the end of `nuxt build` by atinux · Pull Request #1663 · nuxt/cli
Conversation
atinux
commented
Nov 8, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
Written by an AI agent on behalf of @atinux. @atinux has not reviewed it yet.
Stacked on #1662 (quieter server build output). Review that one first; this diff only adds the client summary on top of it.
After nuxt build, Vite lists every client file with a hashed name (_nuxt/IS_fkJ2V.js 117.31 kB). That tells you nothing about why the bundle is that size: which packages are in it, what every page has to download, or what to change to make it smaller.
What changed
nuxt build (and nuxt generate) now end with a client bundle summary:
- the total size, raw and gzip, and what every page loads (the entry, its static imports and their CSS)
- size by package, each with a bar and percentage of the whole client bundle; your own code and Nuxt/Vite virtual modules get one row each
- the largest chunks, each with its role (
entry, every page, lazy app/pages/ws.vue, shared by N chunks) and its main contents
- hints: a package bundled more than once (each version and what imports it), and a package other than Vue, Nuxt, vue-router or unhead that adds 50 kB or more to every page (with the file that imports it)
- a pointer to
npx nuxt-bundle-analyzer for the full picture
- Vite's per-file client listing is hidden, and so is Vite's own gzip pass on the client (
reportCompressedSize: false), since the summary computes gzip itself.
- Projects need no setup. The CLI registers a small Vite plugin on
vite:extendConfig that reads the Rolldown bundle in generateBundle, along with getModuleInfo importers. It does nothing with --logLevel silent or with webpack/rspack.
Evidence
The playground, nuxt build, exit code 0, client section only (the Nitro part comes from #1662).
Before (on main; #1662 doesn't touch the client output):
● Bundling client
ℹ Building client...
ℹ vite v8.3.5 building client environment for production...
transforming...
✓ 170 modules transformed.
rendering chunks...
computing gzip size...
ℹ .nuxt/dist/client/manifest.json 3.49 kB │ gzip: 0.52 kB
.nuxt/dist/client/_nuxt/ws.Owk9mDUs.css 0.08 kB │ gzip: 0.09 kB
.nuxt/dist/client/_nuxt/error-500.BXhsl4_b.css 1.95 kB │ gzip: 0.72 kB
.nuxt/dist/client/_nuxt/error-404.BHD56dvq.css 2.70 kB │ gzip: 0.92 kB
.nuxt/dist/client/_nuxt/D0_HFpjZ.js 0.37 kB │ gzip: 0.28 kB
.nuxt/dist/client/_nuxt/DnmIjkub.js 1.71 kB │ gzip: 0.93 kB
.nuxt/dist/client/_nuxt/BjwMuEZy.js 2.68 kB │ gzip: 1.18 kB
.nuxt/dist/client/_nuxt/7P8NNFxW.js 4.03 kB │ gzip: 1.72 kB
.nuxt/dist/client/_nuxt/BY4l5XNd.js 75.54 kB │ gzip: 29.28 kB
.nuxt/dist/client/_nuxt/IS_fkJ2V.js 117.31 kB │ gzip: 42.79 kB
ℹ ✓ built in 492ms
✔ Client built in 518ms
After:
● Bundling client
ℹ Building client...
ℹ vite v8.3.5 building client environment for production...
transforming...
✓ 170 modules transformed.
rendering chunks...
ℹ ✓ built in 788ms
✔ Client built in 820ms
Bundle (client) 208.41 kB (77.73 kB gzip) 6 JS, 3 CSS
Every page loads 194.83 kB (71.86 kB gzip)
By package size gzip
@vue/runtime-core 58.52 kB 22.37 kB ██████░░░░░░░░░░░░░░ 28%
nuxt 52.52 kB 19.38 kB █████░░░░░░░░░░░░░░░ 25%
vue-router 23.61 kB 8.50 kB ██░░░░░░░░░░░░░░░░░░ 11%
@vue/reactivity 15.85 kB 6.06 kB ██░░░░░░░░░░░░░░░░░░ 8%
unhead 14.37 kB 5.17 kB █░░░░░░░░░░░░░░░░░░░ 7%
@vue/runtime-dom 10.45 kB 3.76 kB █░░░░░░░░░░░░░░░░░░░ 5%
ofetch 4.22 kB 1.52 kB █░░░░░░░░░░░░░░░░░░░ 2%
devalue 3.94 kB 1.42 kB █░░░░░░░░░░░░░░░░░░░ 2%
+10 more, 20.16 kB
Largest chunks size gzip
_nuxt/D12lO5Zl.js 117.06 kB 42.13 kB entry nuxt, vue-router, unhead +11
_nuxt/BfoCKmgC.js 77.77 kB 29.73 kB every page @vue/runtime-core, @vue/rea…
_nuxt/AcsGaTxq.js 4.03 kB 1.72 kB lazy error-404.vue (nuxt)
_nuxt/CFKm4oDl.js 2.68 kB 1.18 kB lazy error-500.vue (nuxt)
_nuxt/RWmzdlYL.js 1.72 kB 927 B lazy app/pages/ws.vue
_nuxt/B_e7YRdB.js 379 B 278 B lazy app/pages/index.vue
See what each chunk imports with npx nuxt-bundle-analyzer
A throwaway app with yaml imported in app.vue, acorn in a <LazyEditor> component, and two semver versions (7.8.5 directly, 6.3.1 through a local legacy package), coloured, full build output:

Also checked:
playground-nightly (Nuxt 5 nightly, where Nitro runs the Vite environment build): the summary prints and the client file list is hidden.
pnpm test:types, eslint and knip pass.
- The new
client-bundle.spec.ts tests pass: the initial-load set, package attribution including nested copies, duplicate importers, the hint rules, and row truncation.
- The whole unit suite passes (
env -u NO_COLOR TERM=xterm-256color pnpm exec vitest run packages: 154 files, 2183 tests passed).
Details
- Sizes per package are approximate. Rolldown reports each module's length before minification, so each module gets its share of the chunk's final (minified) size. That's enough to rank packages; nuxt-bundle-analyzer and Sonda use source maps for exact numbers.
- Hiding Vite's list: the CLI wraps Nuxt's Vite
customLogger and drops the messages that name a client file collected in generateBundle. Matching on file names rather than an output directory works whether buildDir is .nuxt or node_modules/.cache/nuxt/.nuxt, and with Nitro writing straight to .output/public. Server output goes through the same logger and is left alone.
- Open questions:
- Should
@vue/* show as one vue row?
- Should the summary be opt-out (a flag or config)?
- Are the hint thresholds right?
- Should the summary say anything for webpack/rspack builds?
ELI5
When you build a Nuxt app, the CLI now tells you how much JavaScript your visitors download, which libraries that weight comes from, and which ones you could load later or deduplicate to make pages lighter.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
atinux
changed the title
feat(build): summarise the client bundle at the end of nuxt build
feat(build): summarise the client app at the end of nuxt build
Nov 8, 2026
atinux
changed the title
feat(build): summarise the client app at the end of nuxt build
feat(build): summarise the app (client) build at the end of nuxt build
Nov 8, 2026
atinux
changed the title
feat(build): summarise the app (client) build at the end of nuxt build
feat(build): summarise the client bundle at the end of nuxt build
Nov 10, 2026
This branch has not been deployed
No deployments
Reviewers
danielroe
Awaiting requested review from danielroe
danielroe will be requested when the pull request is marked ready for review
danielroe is a code owner
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|