Member-only story
Are TypeScript Barrel Files an Anti-pattern?
Barrel files are a popular pattern in Typescript projects for managing imports and exports. Rather than importing dependencies straight from the source file location, we add an intermediary index.ts
file that re-exports a module’s dependencies. Barrel files let us shorten and simplify import statements, prevent the consumer from needing to concern themselves with the internal implementation of the module, and provide a public interface behind which we can freely refactor.
For example, we might have a React component with the following folder structure:
/src/components/componentA
ComponentA.tsx
ComponentA.test.ts
ComponentA.types.ts
ComponentA.styles.ts
index.ts
Within that folder, there are going to be a bunch of export statements passing objects between the files that aren’t relevant to the rest of the application. In most cases, someone consuming this component will only be interested in ComponentA
and perhaps an interface for its properties. With barrel files, we can export just these objects from the folder.
// src/components/componentA/index.ts
export { ComponentA } from './ComponentA.ts';
export { ComponentAProps } from './ComponentA.types.ts';
Then, from another file, we can import from the folder path, rather than specific files.
// src/pages/page.tsx
// By referencing the files directly
import { ComponentA } from 'src/components/componentA/ComponentA';
import { ComponentAProps } from 'src/components/componentA/ComponentA.types';
// By referencing index.ts
import { ComponentA, ComponentAProps } from 'src/components/componentA';
Barrel files can be nested, and we could place an additional index.ts
file at the root of our components
directory. Using this higher-level index file, we can then roll up multiple imports from the components
directory into a single statement.
// src/components/index.ts
export * from './componentA';
export * from './componentB';
export * from './componentC';
// src/pages/page.tsx
import { ComponentA, ComponentB } from 'src/components';
Most of the third-party libraries we use have barrel files threaded throughout their structure. For example, if you’re using Material-UI, you’re probably used to…