Renaming with as
Rename an import when two names would clash or a name is unclear.
import { format as formatDate } from "./dates.js";
import { format as formatMoney } from "./money.js";
formatDate(new Date());
formatMoney(12.5);
You can also rename on export:
function internalName() { /* ... */ }
export { internalName as publicName };
Namespace imports
import * as dates from "./dates.js";
dates.format(new Date());
dates.parse("2026-03-15");
All exports become properties of one object. It makes it obvious where a function comes from.
Re-exporting
A module can export things that came from another module, without using them itself.
export { add, subtract } from "./math.js";
export { default as Logger } from "./Logger.js";
export * from "./strings.js"; // everything named from strings.js
export * from does not re-export a default export. Handle that with export { default } from "./x.js" or the as form above.
Barrel files
A file that collects and re-exports a folder’s modules is called a barrel, often named index.js.
utils/
math.js
strings.js
dates.js
index.js ← export * from "./math.js"; export * from "./strings.js"; ...
// One import instead of three
import { add, capitalize, formatDate } from "./utils/index.js";
When barrels help and hurt
Help: shorter imports, and one place that defines a folder’s public interface.
Hurt:
- They can make bundlers load more code than needed if tree shaking is not effective.
- They can create circular imports and confusing dependency graphs.
- Jumping to the real definition in your editor takes one more step.
For small projects, a barrel is harmless and tidy. In large ones, many teams import directly from the file that defines the thing.
Practical tip
If a project’s imports become a mess, first agree on a convention (named exports, one folder per feature, barrels only at feature boundaries), then apply it consistently.