Bundle analyzer
Skill imtiazrayhan/agentscamp-library/skills/bundle-analyzer
Analyze a JS/TS production bundle and surface the biggest size wins — heavy dependencies, duplicate packages, missing code-splitting, oversized polyfills, and dev/server code leaking into the client. Use when a bundle is too large and you need a ranked, actionable reduction plan.From its SKILL.md
npx -y skills add imtiazrayhan/agentscamp-library --skill bundle-analyzerAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
- runs commandsInstructs the agent to run 6 commands, including `ANALYZE=true npm run build` and 5 more.
SKILL.md
6.9 KB, ~1.6k tokens by cl100k_base, as published. Nobody here has run it
Inspect a JavaScript/TypeScript production bundle and find where the bytes actually go. The skill builds a stats report, attributes weight to specific modules and packages, and hunts for the patterns that bloat bundles in practice — a 200KB date library imported for one helper, two copies of the same package at different versions, a route that ships eagerly instead of lazily, a polyfill set targeting browsers you dropped years ago, or server-only code that slipped past the client boundary. It returns a ranked list of concrete reductions with the estimated savings of each, so you fix the 80KB win before the 4KB one.
When to use this skill
- A production bundle (or a specific route/chunk) has grown past budget and you need to know exactly what to cut.
- You suspect duplicate packages, a heavyweight dependency, or a barrel import dragging in a whole library.
- A first-load or main chunk is too big and you want to know what should be code-split or deferred.
- You want to confirm dev-only tooling, source maps, or server code is not leaking into the client bundle.
[!NOTE] Always measure the production build, not dev. Dev bundles include HMR runtime, unminified source, and no tree-shaking, so their sizes are meaningless for this analysis. Compare gzip/brotli transfer sizes, not raw bytes — that is what users actually download.
Instructions
- Locate the build and detect the bundler. Identify the toolchain before doing anything — do not guess. Check
package.jsonscripts and lockfiles fornext,vite,webpack,rollup,esbuild, or@remix-run. Note the package manager (package-lock.json,pnpm-lock.yaml,yarn.lock,bun.lockb) since duplicate-detection commands differ per manager. - Produce a stats report using the project's own analyzer. Match existing config rather than bolting on a new tool:
- Next.js — run the production build and read its per-route First Load JS table; if
@next/bundle-analyzeris wired up, runANALYZE=true npm run build. - Vite/Rollup — use
rollup-plugin-visualizerif present, or build and inspectdist/assets/*sizes. - Webpack — generate
--jsonstats (webpack --profile --json=stats.json, which writes the file directly so console warnings don't corrupt the JSON) and analyze, e.g. withsource-map-explorerover the emitted bundle + map. - If no analyzer is configured, fall back to
npx source-map-explorer 'dist/**/*.js'against the built output and its source maps.
- Next.js — run the production build and read its per-route First Load JS table; if
- Attribute weight to packages, not just files. Map the largest modules back to their npm packages. For each heavyweight dependency, determine whether it is fully used or pulled in by a barrel/side-effect import, and whether a lighter alternative exists (e.g.
date-fns/dayjsovermoment, nativeIntlovernumeral,lodash-eswith named imports overlodash). - Detect duplicates and version skew. Run
npm ls <pkg>/pnpm why <pkg>/yarn why <pkg>on suspect packages to find the same library bundled at multiple versions, and check for both ESM and CJS copies of the same dep. Flag candidates forresolutions/overridesor dedupe. - Find missing code-splitting and oversized polyfills. Look for large modules in the entry/main chunk that are only needed on one route or behind an interaction (charts, editors, markdown renderers, PDF libs) — these belong behind
import()/next/dynamic/React.lazy. Inspect the polyfill/transpile target (browserslist,targetintsconfig/vite/tsup) forcore-jsor regenerator-runtime bloat aimed at browsers you no longer support. - Hunt for leaked dev/server code. Grep the client bundle and imports for things that should never ship: test/mock files,
process.envdebug branches, server-only modules (fs,cryptoserver usage, DB clients, secrets), and dev dependencies imported from app code. In Next.js, confirm Server Component /"use client"boundaries are not dragging server modules into client chunks. - Verify each proposed cut. Do not estimate from intuition alone. Where feasible, apply the change behind the analyzer (or
--dry) and re-run the build to measure the real delta. At minimum, cite the measured pre-change size from the stats report for every finding. - Report a ranked plan. Output findings ordered by estimated gzip savings, each with: the module/package, current size, the specific fix, the expected reduction, and a rough effort/risk rating. Flag anything you could not measure precisely so the user knows what to confirm.
[!WARNING] Tree-shaking only works on side-effect-free ESM. A default or namespace import from a CJS package (or a package missing
"sideEffects": false) pulls in the whole module regardless of what you use — so "import one helper" can still cost the full library. Verify the import shape, not just the import statement.
Examples
A ranked findings report for a Next.js app whose largest route shipped 412 KB of First Load JS:
Bundle analysis — route /dashboard (First Load JS: 412 KB gzip → target 180 KB)
Ranked by estimated gzip savings:
1. moment + moment-timezone .................. 71 KB [HIGH]
Imported in 3 files for formatting only. Replace with date-fns
named imports (tree-shakeable). Est. -64 KB. Effort: M, Risk: low.
2. Duplicate react (18.2.0 + 18.3.1) .......... 44 KB [HIGH]
`npm ls react` shows two copies via an old @charting/core dep.
Add an override to pin a single version + dedupe. Est. -44 KB.
Effort: S, Risk: low.
3. recharts loaded eagerly in entry chunk ..... 38 KB [HIGH]
Only rendered below the fold on /dashboard. Move behind
next/dynamic({ ssr: false }). Est. -38 KB from First Load.
Effort: S, Risk: low.
4. lodash default import (whole library) ...... 24 KB [MED]
`import _ from "lodash"`. Switch to `lodash-es` + named imports
(debounce, groupBy). Est. -21 KB. Effort: S, Risk: low.
5. core-js polyfills for IE11 ................. 19 KB [MED]
browserslist still includes "ie 11". Drop it (no IE traffic in
analytics). Est. -19 KB. Effort: S, Risk: med (confirm targets).
6. server-only `pg` Pool pulled into client ... 12 KB [HIGH]
db/client.ts imported from a "use client" component. Move the
query behind a Server Action / route handler. Est. -12 KB +
removes a secret-leak vector. Effort: M, Risk: med.
Estimated total reduction: ~198 KB gzip (412 → ~214 KB).
Top 3 fixes alone recover 146 KB. Re-run the analyzer after each.
Re-run the build after applying the top findings to confirm the measured First Load JS dropped as projected, and re-check npm ls to verify the duplicate is gone.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.