Typescript pnpm monorepo, Path Aliases Conflicts Between Local Dependencies During Build

Monorepo builds fail when aliases overlap or diverge solve it by defining clear alias scopes per package and mirroring paths in both TypeScript and bundlers.

The Challenge

You’re using pnpm monorepo workspaces and TypeScript. You want to use path aliases (like @shared/*), but during build you hit conflicts especially when multiple packages or apps define the same alias, or when Next.js/Vite can’t resolve them as expected.

The Anatomy of a Conflict

  • Duplicate Alias Names: Multiple packages define the same alias (e.g. @/ or @shared/*), so it’s ambiguous during build.
  • Alias doesn’t match Package Name: The alias doesn’t match the package name so the bundler or TS can’t resolve it.
  • Bundler/TSConfig mismatch: TS and your bundler (Next.js, Vite, etc.) have different alias configs and you get runtime or build errors.
  • No Unique Package Names: Packages don’t have unique names in package.json so aliasing and resolution is fragile.

Step-by-Step: The Conflict-Free Path

Avoid path alias conflicts in monorepos by following this clean, structured approach to naming, aliasing, and configuration across tools.

1. Give Every Package a Unique Name

json
// packages/shared/package.json{   "name": "@yourorg/shared",   "version": "1.0.0" }
Unique names prevent collision and aid in path mapping.

2. Use Distinct Aliases Per Package

  • Don’t use the same alias (like @/) in multiple projects.
  • Instead, scope each alias to its package:

json

// packages/ui/tsconfig.json{   "compilerOptions": {     "baseUrl": ".",     "paths": {       "@ui/*": ["./src/*"]     }   } }   // apps/web/tsconfig.json {   "compilerOptions": {     "baseUrl": ".",     "paths": {       "@/*": ["./src/*"], // app-local       "@ui/*": ["../../packages/ui/src/*"] // shared package     }   } }
This ensures each alias points to exactly one place and avoids overlap.

3. Mirror Alias Config in Your Bundler

js

// next.config.jsconst withTM = require('next-transpile-modules')(['@yourorg/shared']); module.exports = withTM({ /* ... */ });

For Vite:

js

// vite.config.tsimport path from 'path'; export default {   resolve: {     alias: {       '@': path.resolve(__dirname, 'src'),       '@ui': path.resolve(__dirname, '../../packages/ui/src'),     },   }, };
Always keep alias settings in sync between tsconfig and your bundler.
Also Read: How to Convert HTML Website to ReactJS?

4. Reference the Correct Paths in tsconfig

  • In the consuming app’s tsconfig.json, point aliases to the relative path of the shared package’s source:

json

{  "compilerOptions": {     "paths": {       "@yourorg/shared/*": ["../../packages/shared/src/*"]     }   } }
This enables both type-checking and runtime resolution.

5. Avoid Overlapping Wildcard Aliases

  • Never use a catch-all alias like @/* in more than one package it will cause conflicts.
  • Always scope with the package name or a unique prefix.

Common Pitfalls & Quick Fixes

Pitfall

Example

Fix

Duplicate alias @/ in many All packages use @/*: ./src/* Use @ui/*, @shared/*, etc., per package
Alias not matching package Alias: @shared/*, package: ui Match alias to package: @ui/* for ui package
Only tsconfig, not bundler Alias in tsconfig, not in Vite/Next.js Mirror alias config in both tsconfig and bundler
No unique package name "name": "shared" "name": "@yourorg/shared" in package.json

Pro Tips

  • If you use Next.js, always transpile shared packages with next-transpile-modules.
  • If you hit persistent conflicts, consider using relative imports as a last resort—they’re less pretty, but always work.
  • For large monorepos, tools like Nx or Turborepo help manage project references and aliases at scale.
  • Keep your tsconfig and bundler configs DRY: Use a base config and extend it in each package/app.
Related

Understanding the Problem When building React applications, especially Single Page Applications (SPAs) using React Router, you might expect the page to scroll to the top…

10 Oct, 2025

File Structure (Simplified) When you create a new React app using CRA, your project structure looks like this: my-app/├── public/ │   └── index.html  …

07 Oct, 2025

Finding skilled ReactJS developers in Europe can be challenging. Companies need reliable partners for dedicated development team, staff augmentation or project based hires ensuring timely…

22 Sep, 2025
Request a Quote Schedule a Meeting