Setup NX Library

How to setup an NX library in the monorepo and how to build it

Setup NX Library - Complete Configuration Guide

⚠️ CRITICAL: If you skip the path mapping configuration in Step 3, your library build WILL FAIL with "Cannot find module" errors!

Quick Start (5 Steps)

# 1. Generate library
npx nx g @nx/angular:library my-library --directory=libs/my-library --standalone

# 2. Configure build (see Step 2 below)
# 3. Configure path mappings (see Step 3 below) ⚠️ CRITICAL
# 4. Build dependencies first
nx build core-models storage-system

# 5. Build your library
nx build my-library

Step 1: Generate the Library

npx nx g @nx/angular:library my-library \
  --directory=libs/my-library \
  --importPath=@my-library \
  --standalone \
  --style=scss \
  --skipTests=false

Step 2: Configure Custom Builder

Edit libs/my-library/project.json:

{
  "name": "my-library",
  "tags": ["npm:public", "scope:ui", "type:library"],
  "implicitDependencies": ["core-models", "storage-system"],  // ← Dependencies
  "targets": {
    "build": {
      "executor": "nx:run-commands",
      "outputs": ["{workspaceRoot}/dist/libs/my-library"],
      "options": {
        "command": "node tools/scripts/build/build-angular-library.js my-library"
      },
      "configurations": {
        "production": {
          "command": "node tools/scripts/build/build-angular-library.js my-library"
        }
      },
      "defaultConfiguration": "production"
    }
  }
}

Step 3: Configure Path Mappings ⚠️ CRITICAL

🚨 THIS IS THE MOST COMMON MISTAKE - DON'T SKIP THIS!

Edit libs/my-library/tsconfig.lib.json:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "../../dist/libs/my-library",
    "declaration": true,
    "declarationMap": true,
    "inlineSources": true,
    "incremental": false,
    "types": ["node"],
    "paths": {
      // ⚠️ CRITICAL: Point to dist folders, NOT source!
      "@libs-foundational/core-models": ["../../dist/libs/core-models/src/index"],
      "@libs-foundational/core-models/*": ["../../dist/libs/core-models/src/*"],
      "@storage-system": ["../../dist/libs/storage-system/index"],
      "@storage-system/*": ["../../dist/libs/storage-system/*"]
      // Add more dependencies as needed
    }
  },
  "files": [],
  "include": ["src/**/*.ts"],
  "exclude": [
    "src/**/*.spec.ts",
    "src/**/*.test.ts",
    "jest.config.ts",
    "vite.config.ts",
    "vitest.config.ts"
  ]
}

🎯 Why Different Paths?

Different libraries use different builders with different output structures:

Builder Output Path Example
@nx/js:tsc dist/libs/X/src/ core-models
Custom builder dist/libs/X/ storage-system, auth-ui

Always check the actual dist output:

ls -la dist/libs/core-models/
ls -la dist/libs/storage-system/

Step 4: Build Dependencies First

# Build in dependency order
nx build core-models
nx build storage-system
nx build my-library

Common Errors & Solutions

❌ Error: "Cannot find module '@libs-foundational/core-models'"

Cause: Missing or incorrect path mappings in tsconfig.lib.json

Solution: Add explicit path mappings (see Step 3)

"paths": {
  "@libs-foundational/core-models": ["../../dist/libs/core-models/src/index"]
}

❌ Error: "File X is not under 'rootDir'"

Cause: TypeScript trying to compile dependency source instead of using dist

Solution: Ensure paths point to dist/ folders, not src/

❌ Error: "Duplicate identifier 'config'"

Cause: Using same name for @Input() setter and computed signal

Solution: Use private signal _config and access it directly in template:

// DON'T DO THIS:
@Input() set config(value: T) { this._config.set(value); }
readonly config = computed(() => this._config());  // ❌ Duplicate!

// DO THIS:
@Input() set config(value: T) { this._config.set(value); }
// Use _config() directly in template

Complete Example: Creating @auth-ui

# 1. Generate
npx nx g @nx/angular:library auth-ui \
  --directory=libs/auth-ui \
  --importPath=@auth-ui \
  --standalone \
  --style=scss

# 2. Update project.json
cat > libs/auth-ui/project.json <<EOF
{
  "name": "auth-ui",
  "tags": ["npm:public"],
  "implicitDependencies": ["core-models", "storage-system"],
  "targets": {
    "build": {
      "executor": "nx:run-commands",
      "outputs": ["{workspaceRoot}/dist/libs/auth-ui"],
      "options": {
        "command": "node tools/scripts/build/build-angular-library.js auth-ui"
      }
    }
  }
}
EOF

# 3. Update tsconfig.lib.json (⚠️ CRITICAL)
cat > libs/auth-ui/tsconfig.lib.json <<EOF
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "../../dist/libs/auth-ui",
    "incremental": false,
    "types": ["node"],
    "paths": {
      "@libs-foundational/core-models": ["../../dist/libs/core-models/src/index"],
      "@storage-system": ["../../dist/libs/storage-system/index"]
    }
  },
  "include": ["src/**/*.ts"],
  "exclude": ["src/**/*.spec.ts"]
}
EOF

# 4. Build dependencies
nx build core-models
nx build storage-system

# 5. Build library
nx build auth-ui

Path Mapping Quick Reference

For Libraries Using @nx/js:tsc (e.g., core-models)

{
  "@libs-foundational/core-models": ["../../dist/libs/core-models/src/index"],
  "@libs-foundational/core-models/*": ["../../dist/libs/core-models/src/*"]
}

Output: dist/libs/core-models/src/index.js

For Libraries Using Custom Builder (e.g., storage-system)

{
  "@storage-system": ["../../dist/libs/storage-system/index"],
  "@storage-system/*": ["../../dist/libs/storage-system/*"]
}

Output: dist/libs/storage-system/index.js

For Theme System

{
  "@theme-system": ["../../dist/libs/theme-system/theme-runtime/index"],
  "@theme-system-theme-styles": ["../../dist/libs/theme-system/theme-styles/index"]
}

Checklist Before Building


TL;DR - Just Copy This

Minimal tsconfig.lib.json for most libraries:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "../../dist/libs/YOUR-LIBRARY-NAME",
    "declaration": true,
    "declarationMap": true,
    "inlineSources": true,
    "incremental": false,
    "types": ["node"],
    "paths": {
      "@libs-foundational/core-models": ["../../dist/libs/core-models/src/index"],
      "@libs-foundational/core-models/*": ["../../dist/libs/core-models/src/*"],
      "@storage-system": ["../../dist/libs/storage-system/index"],
      "@storage-system/*": ["../../dist/libs/storage-system/*"]
    }
  },
  "files": [],
  "include": ["src/**/*.ts"],
  "exclude": [
    "src/**/*.spec.ts",
    "src/**/*.test.ts",
    "jest.config.ts",
    "vite.config.ts",
    "vitest.config.ts"
  ]
}

Replace YOUR-LIBRARY-NAME and add any other dependencies you use.


See Also