CLI tool
bencoveney/barrelsby avatar
bencoveney/barrelsby

barrelsby turns a directory tree into TypeScript barrel files on demand

Automatic TypeScript barrels (index.ts files) for your entire code base

602 stars49 forksTypeScriptMIT

At a glance

What is it?
barrelsby is a Node CLI that walks a set of root directories and writes index.ts barrel files for them, with a flag for where barrels land, a flag for how the exports are structured, and file-level controls for quote style, semicolons and headers. It is a code generator you run from a package.json script, not a runtime dependency.
Who is it for?
barrelsby suits TypeScript code bases with many sibling modules that are imported one by one, and teams willing to regenerate barrels from a script rather than maintain them by hand. It is the wrong tool for a small project where a handful of direct imports read better, for code bases that depend on tree shaking, or for anyone who needs a published release, since the newest tag is v2.8.1 from 2023-09-14 even though the last push was on 2026-10-02.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 22 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What a barrel is and what barrelsby writes for you

A barrel is a file that rolls up exports from several modules into one, usually called index.ts. The README makes the argument with a before-and-after pair. The messy version imports five control modules one line at a time:

ts
import {DropDown} from "./src/controls/DropDown";
import {TextBox} from "./src/controls/TextBox";
import {CheckBox} from "./src/controls/CheckBox";
import {DateTimePicker} from "./src/controls/DateTimePicker";
import {Slider} from "./src/controls/Slider";

The barrel version rolls those up into a single index.ts:

ts
export * from "./DropDown";
export * from "./TextBox";
export * from "./CheckBox";
export * from "./DateTimePicker";
export * from "./Slider";

barrelsby generates that second file across your whole code base rather than one directory at a time. Its description is automatic TypeScript barrels for your entire code base, and the tool is a CLI you install as a development dependency and run from a script.

The audience is a TypeScript team with a directory convention, where the same group of modules keeps being imported together and the import block at the top of every file grows. The tool is a code generator: it writes files, and it can rewrite them, which is worth keeping in mind before pointing it at a large tree.

Where the barrels land is a separate decision from how they look

Two flags control the output shape, and keeping them apart makes the tool much easier to reason about.

The location flag, -l or --location, decides which directories receive a barrel. It defaults to top, which creates a barrel only in the target directory. The below mode creates one in every directory just below the target. The all mode creates a barrel in every directory below and including the target. The replace mode is the conservative one, creating barrels only where one already existed. The branch mode creates a barrel in every directory that itself contains other directories.

The structure flag, -s or --structure, decides what goes inside a barrel, and it defaults to flat. In flat mode modules are exported without nesting:

ts
export * from "./barrel";
export * from "./index";
export * from "./directory2/script";
export * from "./directory2/directory4/deeplyNested";
export * from "./directory3/program";

The filesystem mode instead exports modules as a nested structure that matches the file system directories, which produces a considerably larger file:

ts
import * as barrelts from "./barrel";
import * as directory2directory4deeplyNestedts from "./directory2/directory4/deeplyNested";
import * as directory2scriptts from "./directory2/script";
import * as directory3programts from "./directory3/program";
import * as indexts from "./index";
export {barrelts as barrel};
export const directory2 = {
  directory4: {
    deeplyNested: directory2directory4deeplyNestedts,
  },
  script: directory2scriptts,
};

Flat mode keeps a barrel small and readable. Filesystem mode buys a tree-shaped public API, at the cost of a generated file that is mostly mechanical.

Flags that change the text of the generated file

Once the location and structure are settled, a set of flags adjust the literal content of what gets written.

The exportDefault flag, -E or --exportDefault, also exports the default export of the file, and the documentation notes that it currently works only with the flat mode. It produces two lines per module:

ts
export * from "./barrel";
export { default as barrel } from "./barrel";

The fullPathname flag, -F, works together with exportDefault to give the default export a name derived from the full path, which is what keeps two defaults with the same file name from colliding:

ts
export * from "./example/of/the/path";
export { default as exampleOfThePath } from "./example/of/the/path";

Four more are cosmetic but matter for a generated file that lands in a repository with a style guide. -q or --singleQuotes uses single quotes instead of the default double quotes. -S or --noSemicolon omits semicolons from the end of lines. -H or --noHeader omits the header comment added to the top of the barrel file. And -n or --name sets the file name used for new barrels and for identifying old ones, with .ts appended if you leave it out, defaulting to index.ts.

Two flags govern what gets picked up. -i or --include keeps only files whose paths match the given regular expressions, and -e or --exclude drops files whose paths match. The -L or --local flag prevents barrels from including modules that exist in the same directory, rather than recursively searching child directories.

Install it as a dev dependency and run it from a script

The documented install is a development dependency, which is the right shape for a generator:

bash
npm install --save-dev barrelsby

Next, add a script to your package.json so the generation is repeatable rather than something a developer remembers to run:

json
{
  "scripts": {
    "generate-barrels": "barrelsby --delete"
  }
}

With that in place the barrels are generated by running the script:

bash
npm run generate-barrels

Notice that the example script passes the delete flag, which is worth understanding before you copy it. The -D or --delete option deletes any existing barrels encountered by barrelsby, and it is disabled by default. So the example is the destructive configuration: it removes the barrels it finds and writes fresh ones. If you would rather see what changes first, run barrelsby without that flag, look at the diff in your working tree, and only then decide to make deletion the default.

The tool also offers -v or --version to print the barrelsby version number, -h or --help to display the accepted command line arguments, and -V or --verbose for additional debug information.

Configuration files that stay compatible with older versions

Every command line option can also live in a configuration file, and the -c or --config flag points at its location. That file must be a .json file, and any option can be written using its long name.

The directory option accepts either a single path or a list of paths, and the documentation calls this backwards compatible with previous versions, noting that existing configuration files will be parsed correctly. The two forms behave identically:

json
{
  "directory": "./src"
}
json
{
  "directory": ["./src"]
}

The repository itself keeps both forms on disk. There is a barrelsby.json at the top level and a barrelsby-legacy-directory.json beside it, which is a convenient artifact for anyone reading the code, since it shows the two shapes side by side in the project's own tree.

The default for the directory option is the current directory, so running the tool without -d and without a configuration file scans wherever you happen to be. That default is the one to watch: barrelsby -D in the wrong working directory rewrites barrels across a tree you did not intend to touch, which is the argument for passing -d "./src" explicitly or for keeping the configuration file under version control.

Where barrelsby stops being the right answer

The documentation is detailed about flags and thin about consequences, so a few boundaries are worth stating plainly.

The first is the pairing between flags and modes. The exportDefault flag currently works only with the flat mode, and the fullPathname flag works only with the flat mode together with exportDefault. A team that has settled on filesystem structure cannot use the default-export handling at all, and the tool will not tell you that with a warning.

The second is what delete does. The delete option removes any existing barrels encountered by barrelsby, and the documentation does not describe a dry run, a diff or a confirmation prompt. The verbose flag prints additional debug information, but that is not the same as a preview of the changes.

The third is the generated content itself. In filesystem mode the output is a long list of aliased imports and nested const objects, and every line of it is regenerated on each run. Any hand edit inside a barrel is lost the next time the script runs, which is fine if barrels are treated as build output and awkward if a developer has started adding a comment or a deliberate re-export there.

Finally, the requirement statement is inconsistent across the files. The README says the project requires node v6.0.0 or greater for ES6 syntax, while the engine field in package.json declares node >=0.10. Neither matches the modern Node versions the tool actually runs on, so treat both as stale documentation rather than as a support statement.

Alternatives: other generators, and no barrel at all

The README lists two alternatives by name, Barrelbot and creeate-index, with links and no further description. Since the project itself gives no detail about either, the honest comparison cannot be made from these files, and picking between them would mean reading each project separately.

The comparison that can be made from this repository is the one between generating barrels and not having them. The README's own before-and-after example shows the trade honestly. Direct imports keep the dependency list of each file visible and specific, and nothing in a barrel file needs to be regenerated when a file is added. A barrel replaces five import lines with one, but it also hides which module a symbol actually came from, since export * re-exports whatever a module exposes.

That is the difference in approach between barrelsby and leaving the imports alone. barrelsby is a generator that turns a directory scan into files, so it inherits the strengths and weaknesses of that approach. It removes the repetitive editing when a new sibling module joins a group, and it introduces generated files that must be regenerated, excluded from hand editing and kept consistent with the directory tree.

A middle path is to run the generator only over directories where the grouping is stable, using the include and exclude patterns to bound it, and to leave the rest of the code base with direct imports. The replace location mode does something similar, since it only writes barrels in directories that already had one.

MIT licensing and a release history that has stopped

The licence is MIT, which lets you use the tool in a commercial or internal repository, keep a copy of it, and modify it without any obligation to publish those modifications. For a build-time code generator this is the licence you would hope for, since the output it writes becomes part of your own code base without any licence obligations travelling with it.

The maintenance picture is less comfortable. The recent releases are v2.8.1 from 2023-09-14, v2.8.0 from 2023-05-23 and v2.7.0 from 2023-05-01, so the published package has not moved since September 2023, while the last push was on 2026-10-02. The repository is not archived, so commits continue to land on master, but a fresh install pulls the 2.8.1 line from the npm registry rather than whatever is on that branch. If you need a change that only exists on master, you are building from source yourself.

The project is TypeScript with a small dependency footprint: yargs for the command line and signale for console output, with the CLI entry point at bin/cli.js. Development tooling in package.json includes jest for tests, prettier for formatting, tslint for linting with a prettier config, and a snyk test script. The top level also carries tsconfig.base.json alongside tsconfig.json, a .prettierrc and a .prettierignore, an .editorconfig, and a todo.md.

For an upgrade, the risk is low because the tool only writes files, but the version you install decides which flags exist, so check the flag list in the version you pin against the one your scripts use.

Editorial conclusion

barrelsby suits TypeScript code bases with many sibling modules that are imported one by one, and teams willing to regenerate barrels from a script rather than maintain them by hand. It is the wrong tool for a small project where a handful of direct imports read better, for code bases that depend on tree shaking, or for anyone who needs a published release, since the newest tag is v2.8.1 from 2023-09-14 even though the last push was on 2026-10-02. Verify first by running it with the delete flag turned off in one directory and reading the generated index.ts, then confirm that the location mode and structure mode you chose produce the import shape your existing code expects.

Frequently asked questions

How do I install barrelsby and generate barrels for my project?

Install it as a development dependency with npm install --save-dev barrelsby, add a script such as "generate-barrels": "barrelsby --delete" to your package.json, then run npm run generate-barrels. Without a script, the tool uses the current directory as its root, so pass --directory to point it at your source folder.

What is the difference between the flat and filesystem structure modes in barrelsby?

Flat mode, the default, exports modules without any nesting, so a barrel is a list of export * lines. Filesystem mode exports modules as a nested structure that matches the file system directories, which produces aliased imports and nested const objects instead.

Can barrelsby create a barrel file other than index.ts?

Yes. The --name option specifies the name used for creating new barrels and for identifying old ones, and .ts is appended if you do not include it. Barrel names default to index.ts.

Is it safe to run barrelsby with the --delete flag on a large repository?

The --delete option deletes any existing barrels encountered by barrelsby and is disabled by default. The documentation describes no dry run or diff mode, so run barrelsby without it first and read the changes in your working tree before making deletion the default.

Official sources

  1. bencoveney/barrelsby on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/bencoveney-barrelsby.svg)](https://hysenlabs.com/projects/bencoveney-barrelsby)

Was this useful?