A barrel file is an index.ts whose only job is to re-export other modules, so consumers can write one tidy import instead of five. Almost every TypeScript codebase has them; almost every npm library ships one as its entry point. They look like free organization — and for years the ecosystem treated them that way.

They are not free. Barrel files are quietly behind three of the most common performance complaints in modern React development: bundles that don't tree-shake the way you expect, Next.js dev servers and tsc runs that get slower and hungrier as the app grows, and circular-dependency bugs that surface as Cannot access 'X' before initialization. We maintain @reactuses/core, a library of 120+ React hooks behind exactly one such barrel, and we recently had to rebuild our entire dist layout because of it — a Next.js dev page importing a single hook was pulling a 552 kB client chunk that dropped to 64 kB once the barrel was fixed. This post explains the mechanics behind all three problems and what to do about them, from both sides of the node_modules boundary.

What Is a Barrel File?

A barrel file gathers a directory's public surface into one module:

// src/hooks/index.ts — the "barrel"