Posts
Barrel Roll: Generate TypeScript Exports in VS Code
Meet Barrel Roll, my VS Code extension for generating and updating TypeScript index.ts barrel files from a folder's exported declarations.
In this article
If you maintain an index.ts file that re-exports code from other files, adding a new module usually means updating that export list too. It is simple work, and it is easy to forget.
I created Barrel Roll, a Visual Studio Code extension that generates and updates those barrel files. Right-click a folder, choose a command, and it builds the exports from the TypeScript declarations it finds.
You can install it from the VS Code Marketplace or explore the source on GitHub.
And yes, the name was right there. I was hardly going to call it Manual Export Maintenance Utility.
What Is a Barrel File?
A barrel file collects exports from several modules into a single entry point. In a TypeScript project, that file is often named index.ts.
Suppose you have a small formatting library:
formatting/
currency.ts
options.ts
The source files export a function and a type:
// currency.ts
export function formatCurrency(amount: number): string {
return `$${amount.toFixed(2)}`;
}
// options.ts
export interface FormatOptions {
currency: string;
}
A barrel gives consumers one place to import them:
// index.ts
export { formatCurrency } from './currency.js';
export type { FormatOptions } from './options.js';
Consumer code can then use:
import { formatCurrency, type FormatOptions } from './formatting/index.js';
The generated .js specifiers match the output style documented by Barrel Roll. The example assumes a TypeScript setup that resolves those specifiers to the source modules and emits JavaScript alongside the same relative paths.
As the folder grows, its export list needs to keep up. That is the part Barrel Roll automates.
Right-Click and Generate
After installing the extension, open a TypeScript project and right-click a folder in the Explorer. Under Generate Barrel, choose one of the two commands:
- Barrel Roll Directory processes the selected directory.
- Barrel Roll Directory (Recursive) also generates child-folder barrels and connects them through parent re-exports.
Both commands are also available through the Command Palette. The extension manifest defines these menu entries, and the usage guide describes their behavior.
The extension scans .ts and .tsx source files, excluding index.ts, declaration files, and test files. It detects exported values, type-only exports, and default exports, then creates or updates index.ts.
For the formatting example, the generated barrel separates the function export from the interface’s export type. You get explicit export names instead of having to maintain those lines by hand.
Start with one folder so you can inspect the result. Use recursive generation when you want the same treatment across its child directories.
Keep Updates Easy to Review
Barrel Roll sorts its generated output alphabetically. Running the command again with unchanged exports should produce the same ordering, which keeps the diff focused on what actually changed.
If an index.ts already exists, the update process preserves direct declarations while refreshing re-export lines. For example, a constant declared directly in the index is treated differently from an export pointing at another module. The architecture notes explain the parsing, output generation, and cleanup steps.
That does not mean every handwritten index can be merged without review. Re-export lines are being regenerated, and malformed export syntax may need manual cleanup. Check the diff and run your project’s type check after generation.
The useful result is a small, readable export file that you can inspect quickly.
Choose Where You Want a Barrel
I find barrels useful when a directory represents a deliberate public entry point, such as the exports of a library. Consumers get a defined set of imports, while the implementation can stay in separate files.
I would still use direct imports between implementation modules. For example, currency.ts can import a supporting type from options.ts without going through the index that re-exports both of them. That keeps the dependency path straightforward.
Also consider which exports should be public before generating a barrel. A symbol exported from a source module may exist for another internal module to use; that alone does not mean it belongs in your package’s public API.
Barrel Roll can build the list. You decide whether that list is appropriate for the folder and its consumers. Recursive generation is convenient once you have made that decision for the directory tree.
The Extension Is Open Source
The repository is available under Apache 2.0. It includes unit and integration tests, plus a VS Code extension-host test that activates the extension, checks its commands, runs generation, and validates the resulting index file.
That last check matters for an editor extension. The parser can work correctly in isolation while command registration or packaging still prevents you from using it in VS Code.
The documented scope is TypeScript and TSX source. Runtime-created named exports cannot be discovered through static parsing. If you find a declaration that produces an incorrect barrel, an issue with a small source example and the expected output is especially helpful.
Give It a Roll
Open VS Code’s Extensions view, search for Barrel Roll, and install the extension from coderrob. You can also go directly to its Marketplace page.
Pick a folder where you already maintain a barrel, run Barrel Roll Directory, and review the generated exports.
My goal is simple: make keeping that index.ts up to date a quick editor command, so adding a module does not come with another round of export-list housekeeping.
-Rob