documentation
Supported Formats
Webpack stats, esbuild metafile, source-map-explorer, and rollup-stats JSON
dendrobundle auto-detects the format by inspecting the top-level structure of the JSON you POST. No format flag needed.
webpack-stats
Generated by running webpack with --json:
npx webpack --profile --json > dist/webpack-stats.json
Or via webpack-bundle-analyzer with generateStatsFile: true:
// webpack.config.js
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = {
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'disabled',
generateStatsFile: true,
statsFilename: 'webpack-stats.json',
}),
],
};
Fields used:
| Field | Purpose |
|---|---|
assets[].name |
Asset file name |
assets[].size |
Asset size in bytes |
assets[].chunkNames |
Which named chunks the asset belongs to |
chunks[].initial |
Whether this is an initial (non-lazy) chunk |
chunks[].files |
Asset file names this chunk maps to |
modules[].name |
Source module path |
modules[].size |
Rendered size in bytes after tree-shaking |
Minimal example:
{
"assets": [
{ "name": "main.js", "size": 412680, "chunkNames": ["main"] },
{ "name": "vendor.js", "size": 1154020, "chunkNames": ["vendor"] }
],
"chunks": [
{ "id": 0, "names": ["main"], "initial": true, "files": ["main.js"] },
{ "id": 1, "names": ["vendor"], "initial": true, "files": ["vendor.js"] }
],
"modules": [
{ "name": "src/app/app.ts", "size": 4812, "chunkNames": ["main"] },
{ "name": "node_modules/react/index.js", "size": 7240, "chunkNames": ["vendor"] }
]
}
esbuild-metafile
Generated with the --metafile CLI flag:
npx esbuild src/index.ts --bundle --metafile=dist/meta.json --outfile=dist/bundle.js
Or via the JavaScript API:
import * as esbuild from 'esbuild';
const result = await esbuild.build({
entryPoints: ['src/index.ts'],
bundle: true,
outfile: 'dist/bundle.js',
metafile: true,
});
require('fs').writeFileSync('dist/meta.json', JSON.stringify(result.metafile));
Fields used:
| Field | Purpose |
|---|---|
outputs[key].bytes |
Total output file size |
outputs[key].inputs |
Map of input file → bytes contributed |
outputs[key].entryPoint |
Entry point that produced this output |
Minimal example:
{
"inputs": {},
"outputs": {
"dist/bundle.js": {
"bytes": 412680,
"entryPoint": "src/index.ts",
"inputs": {
"src/index.ts": { "bytesInOutput": 4812 },
"src/app/router.ts": { "bytesInOutput": 2140 },
"node_modules/react/index.js": { "bytesInOutput": 7240 }
}
},
"dist/vendor.js": {
"bytes": 1154020,
"inputs": {
"node_modules/react-dom/index.js": { "bytesInOutput": 580000 }
}
}
}
}
source-map-explorer
Generated by running source-map-explorer with --json:
# Build with source maps first
npm run build -- --sourcemap
# Then extract module breakdown
npx source-map-explorer --json 'dist/*.js' > dist/sme.json
Fields used:
| Field | Purpose |
|---|---|
results[].bundleName |
Output file name |
results[].totalBytes |
Total size of the bundle |
results[].mappedBytes |
Bytes covered by source maps |
results[].files |
Map of source file → bytes |
Minimal example:
{
"results": [
{
"bundleName": "dist/main.js",
"totalBytes": 412680,
"mappedBytes": 398420,
"unmappedBytes": 14260,
"files": {
"src/app/app.ts": { "size": 4812 },
"src/app/router.ts": { "size": 2140 },
"node_modules/react/index.js": { "size": 7240 },
"[unmapped]": { "size": 14260 }
}
}
]
}
Note: source-map-explorer data is only as accurate as your source maps. Production builds with --sourcemap=hidden or --sourcemap=nosources will show reduced coverage.
rollup-stats
Generated by rollup-plugin-visualizer with the raw-data template. Because Vite builds on Rollup, the same plugin covers both Rollup and Vite projects.
// rollup.config.js or vite.config.js
import { visualizer } from 'rollup-plugin-visualizer';
export default {
plugins: [
visualizer({
template: 'raw-data',
filename: 'dist/rollup-stats.json',
gzipSize: true,
brotliSize: true,
}),
],
};
Fields used:
| Field | Purpose |
|---|---|
tree.children[] |
Output chunk files (each top-level node is one asset) |
tree…children[].uid |
Leaf module → its part in nodeParts |
nodeParts[uid].renderedLength |
Module size contributed to the chunk |
nodeParts[uid].gzipLength / brotliLength |
Compressed sizes (when gzipSize/brotliSize enabled) |
nodeMetas[metaUid].id |
Real module path; isExternal modules are excluded |
Minimal example:
{
"version": 2,
"tree": {
"name": "root",
"children": [
{ "name": "main-abc123.js", "children": [{ "name": "src/app.ts", "uid": "u1" }] }
]
},
"nodeParts": {
"u1": { "metaUid": "u1", "renderedLength": 4812, "gzipLength": 1900, "brotliLength": 1700 }
},
"nodeMetas": {
"u1": { "id": "src/app.ts" }
},
"options": { "gzip": true, "brotli": true, "sourcemap": false }
}