SyntaxStudy
Sign Up
TypeScript Path Aliases and Barrel Files
TypeScript Beginner 1 min read

Path Aliases and Barrel Files

TypeScript supports path aliases configured through the paths option in tsconfig.json. Path aliases let you replace long relative import paths like ../../../shared/utils with short absolute-style paths like @shared/utils. This makes imports cleaner, prevents import paths from breaking when files move, and makes the codebase structure more explicit. Barrel files, conventionally named index.ts, re-export the public API of a directory. Instead of importing from the exact file path, consumers import from the directory, and the barrel file resolves to the index. This creates a layer of indirection that lets you reorganise internal file structure without breaking external consumers. The pattern is standard in large TypeScript projects and library development. While barrel files are convenient, they have a significant downside: they can cause circular dependency issues and increase bundle sizes in applications without tree-shaking. Modern bundlers handle them well, but in Node.js environments or older setups, large barrel files can increase startup time. For libraries and internal packages the pattern is generally beneficial; for application code the trade-offs should be considered.
Example
// tsconfig.json path aliases
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@app/*":        ["src/app/*"],
      "@shared/*":     ["src/shared/*"],
      "@features/*":   ["src/features/*"],
      "@utils":        ["src/utils/index.ts"]
    }
  }
}

// src/shared/models/user.model.ts
export interface User { id: number; name: string; email: string }

// src/shared/models/post.model.ts
export interface Post { id: number; title: string; authorId: number }

// src/shared/models/index.ts — barrel file
export type { User }  from "./user.model";
export type { Post }  from "./post.model";

// src/shared/index.ts — top-level barrel
export * from "./models";
export * from "./utils";
export * from "./constants";

// Consuming code — clean imports
import type { User, Post } from "@shared";

// Without alias (messy):
// import type { User } from "../../../shared/models/user.model";

// With alias (clean):
// import type { User } from "@shared";

function getUserPost(user: User, post: Post): string {
    return `${user.name} wrote "${post.title}"`;
}

export { getUserPost };