import-cost-core
raw JSON → 5.5.0 verified Fri May 01 auth: no javascript
Calculate the bundle size of imported packages in JavaScript and TypeScript with a CLI and Node.js API. Version 5.5.0, actively maintained (2025 release). Powered by esbuild and es-module-lexer for high performance — scans 50+ files in less than a second. Provides minified, gzipped, and brotli sizes; identifies tree-shakeable packages; supports budget enforcement, JSON output, ignore patterns, watch mode, and git diff for CI/CD. Works with npm, pnpm, yarn, and bun. Aims to be a drop-in replacement for the deprecated import-cost VS Code extension backend, offering more accuracy and speed than webpack-bundle-analyzer or cost-of-modules.
Common errors
error ReferenceError: Cannot access 'PackageInfo' before initialization ↓
cause Importing `PackageInfo` as a value when it is only a TypeScript type.
fix
Use
import type { PackageInfo } from 'import-cost-core' instead. error Error: Cannot find module 'import-cost-core' ↓
cause Package not installed or not in node_modules.
fix
Run
npm install import-cost-core in your project. error TypeError: importCost is not a function ↓
cause Using default import in ESM when package expects named export, or misconfiguring bundler.
fix
Use
import { importCost } from 'import-cost-core'. error Error: esbuild is not installed ↓
cause Missing peer dependency 'esbuild'.
fix
Run
npm install esbuild alongside import-cost-core. Warnings
gotcha The `importCost` function caches results based on file content. If you call it multiple times with the same content, you might get stale results. Dispose the emitter and create a new one for fresh calculations. ↓
fix Call `emitter.removeAllListeners()` before creating a new emitter for the same file.
gotcha The `PackageInfo` import is a TypeScript type, not a value. Attempting to use it at runtime will throw `ReferenceError: Cannot access 'PackageInfo' before initialization` in CommonJS or `PackageInfo is not defined` in ESM. ↓
fix Use `import type { PackageInfo } from 'import-cost-core'` to import only the type, or use `import { PackageInfo } from 'import-cost-core'` only if you need the runtime value (it does not exist).
deprecated The default export `import importCost from 'import-cost-core'` is deprecated as of v3.0. Use named imports instead. ↓
fix Replace `import importCost from 'import-cost-core'` with `import { importCost } from 'import-cost-core'`.
breaking In v2.0, the function signature changed: `importCost(fileName, fileContents, language)` replaced the old `importCost(fileName, fileContents, language, config)`. The config object is now passed as the fourth argument, but the third argument is now required (previously optional). ↓
fix Update to v3.0+ which restored the optional config parameter or adjust your calls to include the language parameter.
gotcha The `cleanup` function must be called to terminate background esbuild workers. If you don't call it, the Node.js process will not exit cleanly (it will hang). ↓
fix Call `cleanup()` when done, e.g., after the 'done' event or in a process 'exit' handler.
Install
npm install import-cost-core yarn add import-cost-core pnpm add import-cost-core Imports
- importCost
import { importCost } from 'import-cost-core' - Lang
import { Lang } from 'import-cost-core' - PackageInfo wrong
import { PackageInfo } from 'import-cost-core'correctimport type { PackageInfo } from 'import-cost-core' - cleanup
import { cleanup } from 'import-cost-core'
Quickstart
import { importCost, cleanup, Lang } from 'import-cost-core';
import type { PackageInfo } from 'import-cost-core';
const fileName = 'src/index.ts';
const fileContents = `
import express from 'express';
import { readFile } from 'fs/promises';
const _ = require('lodash');
`;
const emitter = importCost(fileName, fileContents, Lang.TYPESCRIPT);
emitter.on('start', (packages: PackageInfo[]) => {
console.log('Calculating sizes for', packages.length, 'packages...');
});
emitter.on('calculated', (pkg: PackageInfo) => {
console.log(`${pkg.name}: minified=${(pkg.size / 1024).toFixed(2)} KB, gzip=${(pkg.gzip / 1024).toFixed(2)} KB, brotli=${(pkg.brotli / 1024).toFixed(2)} KB, tree-shakeable=${pkg.sideEffects === false}`);
});
emitter.on('done', (packages: PackageInfo[]) => {
console.log('All done!');
cleanup();
});
emitter.on('error', (err: Error) => {
console.error('Error:', err.message);
});