DEV Community

Chintan prajapati
Chintan prajapati

Posted on

πŸš€ Stop Killing Your Bundle Size

Automatically Remove Barrel Files in TypeScript

Cover Image Description: A split screen showing a heavy, tangled bundle on the left and a clean, direct import structure on the right.


We all love Barrel Files (index.ts files that export everything from a directory). They make our imports look clean and organized:

// 😍 Looks clean...
import { Button, Header, Footer } from './components';
Enter fullscreen mode Exit fullscreen mode

But what if I told you that this single line of code is likely slowing down your CI/CD, bloating your bundle size, and causing those nightmare "Module is undefined" circular dependency errors?

I built a tool to fix this automatically, and today I’m sharing it with you.

The Hidden Cost of Barrel Files πŸ“‰

When you import a single named export from a barrel file, many bundlers and test runners (like Jest) end up loading every other file exported in that barrel to resolve the module.

  1. Slower Tests: In Jest, importing Button might accidentally load Table, Chart, and HeavyLibrary just because they share an index.ts.
  2. Tree-Shaking Failures: Webpack and Rollup are getting better, but deeply nested barrel files often trick them into including dead code in your production bundle.
  3. Circular Dependencies: This is the big one. If Module A imports Module B via an index, and Module B imports Module A via the same index, you get a runtime crash.

The Solution: Direct Imports πŸ› οΈ

The fix is simple but tedious. You need to convert this:

import { Button } from './components';
Enter fullscreen mode Exit fullscreen mode

Into this:

import { Button } from './components/Button';
Enter fullscreen mode Exit fullscreen mode

Doing this manually for 500+ files is painful. So I automated it.

Introducing: no-barrel-file

I created an open-source CLI tool and GitHub Action that scans your project, finds imports relying on barrel files, and automatically rewrites them to direct paths.

✨ Features

  • Auto-Fix: Rewrites imports safely using ts-morph (AST transformation, not regex).
  • Smart: Respects your tsconfig.json paths and aliases.
  • Flexible: Run it via npx, install it globally, or run it in CI.

πŸ’» 3 Ways to Use It Locally

Whether you want a quick check or a permanent tool for your team, there are three ways to use no-barrel-file.

Method 1: The "One-Off" (No Install)

The easiest way to check a project without installing dependencies is via npx.

# Just list the barrel files
npx no-barrel-file display

# Fix the imports
npx no-barrel-file replace --alias-config-path tsconfig.json
Enter fullscreen mode Exit fullscreen mode

Method 2: The "Project Standard" (Dev Dependency)

If you want to ensure your whole team avoids barrel files, install it as a dev dependency.

npm install -D no-barrel-file
# or
pnpm add -D no-barrel-file
Enter fullscreen mode Exit fullscreen mode

Then, add a script to your package.json:

"scripts": {
  "fix:barrels": "no-barrel-file replace --alias-config-path tsconfig.json",
  "check:barrels": "no-barrel-file display"
}
Enter fullscreen mode Exit fullscreen mode

Now anyone on the team can run npm run fix:barrels.

Method 3: The "Power User" (Global Install)

If you work across many repositories and want this tool available everywhere in your terminal:

npm install -g no-barrel-file

# Now you can run it anywhere
no-barrel-file display
Enter fullscreen mode Exit fullscreen mode

πŸ€– Automate it with GitHub Actions

The best way to maintain code quality is to automate it. I published a GitHub Action so you can ensure no new barrel files creep into your repository.

Option A: Auto-Fix Mode (Recommended)

This workflow detects lazy imports in Pull Requests, fixes them automatically, and pushes the changes back to the branch.

File: .github/workflows/fix-barrels.yml

name: Auto-Fix Barrel Files
on: [pull_request]

permissions:
  contents: write # Required to commit changes

jobs:
  fix-imports:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run No Barrel File
        uses: chintan9/no-barrel-file@v1
        with:
          mode: 'replace'
          alias-config-path: 'tsconfig.json'
          extensions: '.ts,.tsx'

      - name: Commit changes
        uses: stefanzweifel/git-auto-commit-action@v5
        with:
          commit_message: "refactor: resolve barrel file imports"
Enter fullscreen mode Exit fullscreen mode

Option B: Audit Mode

If you prefer not to touch the code automatically but just want to see a report of barrel files in your CI logs:

- name: Audit Barrel Files
  uses: chintan9/no-barrel-file@v1
  with:
    mode: 'display'
    root-path: 'src'
Enter fullscreen mode Exit fullscreen mode

Results

After running this on a medium-sized React project, I saw:

  • Jest startup time: Reduced by ~30%.
  • Circular Dependency Errors: Completely vanished.
  • Bundle Size: Slight reduction (depending on your existing tree-shaking setup).

Try it out!

I’d love to hear your feedback. Give it a star on GitHub if it saves you some time!

Happy coding! πŸš€

Top comments (0)