fast-import-cost

raw JSON →
5.5.0 verified Fri May 01 auth: no javascript

A CLI tool and Node.js library for calculating the bundle size of imported packages in JavaScript and TypeScript files. v5.5.0, actively maintained. Powered by esbuild and es-module-lexer, it offers fast scanning (50+ files in under 1 second) and provides minified, gzipped, and brotli sizes. Differentiators include tree-shaking awareness, a `--budget` flag for CI enforcement, diff support between git branches, and zero-config operation with npm, pnpm, yarn, and bun. Ships TypeScript definitions.

error Error: Cannot find module 'fast-import-cost'
cause Package not installed or ESM-only package imported via require.
fix
Install the package: npm install fast-import-cost. Then use import { ... } from 'fast-import-cost' instead of require().
error TypeError: cleanup is not a function
cause Called cleanup() incorrectly or before importing.
fix
Ensure you import cleanup: import { cleanup } from 'fast-import-cost'; then call cleanup() after emitter is done.
error Error: File not found: /path/relative/file.ts
cause fileName passed to importCost is a relative path instead of absolute.
fix
Use path.resolve(__dirname, 'file.ts') to get absolute path before passing to importCost.
error Error: Event emitter memory leak detected. 11 listeners added to [EventEmitter]. Use emitter.setMaxListeners() to increase limit
cause Multiple importCost emitters created without removing listeners, leading to memory leak warnings.
fix
Call emitter.removeAllListeners() on old emitters before creating new ones, or increase max listeners if appropriate.
gotcha The importCost function returns an EventEmitter that must be cleaned up with cleanup() to avoid resource leaks.
fix Call cleanup() after the emitter emits 'done' or when shutting down your application.
gotcha The fileName must be an absolute path to the file being analyzed; relative paths will cause resolution failures.
fix Use path.resolve() to get an absolute path before passing to importCost.
gotcha The 'start' event may fire with an empty array if no imports are detected; handle this case to avoid confusion.
fix Check packages.length in the 'start' event handler before proceeding.
gotcha ESM-only package; using CommonJS require will throw a runtime error. TypeScript users must set moduleResolution to 'node16' or 'bundler'.
fix Use import statements instead of require(); configure tsconfig.json appropriately.
gotcha The CLI --budget flag sets a size limit in KB. If any import exceeds this, the process exits with code 1. Useful for CI, but note that the budget checks individual imports, not total bundle size.
fix Ensure --budget value is realistic for individual packages, or use --json to custom parse results.
npm install fast-import-cost
yarn add fast-import-cost
pnpm add fast-import-cost

Demonstrates the library API: importCost emitter with start, calculated, done, and error events, plus cleanup.

import { importCost, cleanup, Lang } from 'fast-import-cost';
import type { PackageInfo } from 'fast-import-cost';

const fileName = '/path/to/project/src/app.ts';
const fileContents = `
import express from 'express';
import { createServer } from 'http';
import { ApolloServer } from '@apollo/server';
import * as lodash from '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}: ${(pkg.size / 1024).toFixed(2)} KB (gzip: ${(pkg.gzip / 1024).toFixed(2)} KB, brotli: ${(pkg.brotli / 1024).toFixed(2)} KB)`);
  console.log('Tree-shakeable:', pkg.sideEffects === false);
});

emitter.on('done', (packages: PackageInfo[]) => {
  console.log('All done!');
  const total = packages.reduce((sum, p) => sum + p.size, 0);
  console.log('Total size:', (total / 1024).toFixed(2), 'KB');
});

emitter.on('error', (e: Error) => {
  console.error('Error:', e.message);
});

// Later when done
emitter.removeAllListeners();
cleanup();