Claude Cursor Skill

nx-workspace-patterns

Configure and optimize Nx monorepo workspaces. Use when setting up Nx, configuring project boundaries, optimizing build caching, or implementing affected commands.

LLM Mart · 0 points · 15 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download wshobson-agents-plugins_developer-essentials_skills_nx-workspace-patterns-554237f.zip · 3 KB
Part of wshobson/agents — 170 skills

Install

skills CLI npx skills add https://github.com/wshobson/agents/tree/main/plugins/developer-essentials/skills/nx-workspace-patterns
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install wshobson-agents@llmmart
Git git clone https://github.com/wshobson/agents.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole wshobson/agents collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Nx Workspace Patterns

Production patterns for Nx monorepo management.

When to Use This Skill

  • Setting up new Nx workspaces
  • Configuring project boundaries
  • Optimizing CI with affected commands
  • Implementing remote caching
  • Managing dependencies between projects
  • Migrating to Nx

Core Concepts

1. Nx Architecture

workspace/
├── apps/              # Deployable applications
│   ├── web/
│   └── api/
├── libs/              # Shared libraries
│   ├── shared/
│   │   ├── ui/
│   │   └── utils/
│   └── feature/
│       ├── auth/
│       └── dashboard/
├── tools/             # Custom executors/generators
├── nx.json            # Nx configuration
└── workspace.json     # Project configuration

2. Library Types

Type Purpose Example
feature Smart components, business logic feature-auth
ui Presentational components ui-buttons
data-access API calls, state management data-access-users
util Pure functions, helpers util-formatting
shell App bootstrapping shell-web

Templates and detailed worked examples

Full template library and detailed worked examples live in references/details.md. Read that file when you need the concrete templates.

Best Practices

Do's

  • Use tags consistently - Enforce with module boundaries
  • Enable caching early - Significant CI savings
  • Keep libs focused - Single responsibility
  • Use generators - Ensure consistency
  • Document boundaries - Help new developers

Don'ts

  • Don't create circular deps - Graph should be acyclic
  • Don't skip affected - Test only what changed
  • Don't ignore boundaries - Tech debt accumulates
  • Don't over-granularize - Balance lib count
Files (agents)
  • references
    • details.md 8.6 KB
      # nx-workspace-patterns — templates and worked examples
      
      ## Templates
      
      ### Template 1: nx.json Configuration
      
      ```json
      {
        "$schema": "./node_modules/nx/schemas/nx-schema.json",
        "npmScope": "myorg",
        "affected": {
          "defaultBase": "main"
        },
        "tasksRunnerOptions": {
          "default": {
            "runner": "nx/tasks-runners/default",
            "options": {
              "cacheableOperations": [
                "build",
                "lint",
                "test",
                "e2e",
                "build-storybook"
              ],
              "parallel": 3
            }
          }
        },
        "targetDefaults": {
          "build": {
            "dependsOn": ["^build"],
            "inputs": ["production", "^production"],
            "cache": true
          },
          "test": {
            "inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"],
            "cache": true
          },
          "lint": {
            "inputs": ["default", "{workspaceRoot}/.eslintrc.json"],
            "cache": true
          },
          "e2e": {
            "inputs": ["default", "^production"],
            "cache": true
          }
        },
        "namedInputs": {
          "default": ["{projectRoot}/**/*", "sharedGlobals"],
          "production": [
            "default",
            "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
            "!{projectRoot}/tsconfig.spec.json",
            "!{projectRoot}/jest.config.[jt]s",
            "!{projectRoot}/.eslintrc.json"
          ],
          "sharedGlobals": [
            "{workspaceRoot}/babel.config.json",
            "{workspaceRoot}/tsconfig.base.json"
          ]
        },
        "generators": {
          "@nx/react": {
            "application": {
              "style": "css",
              "linter": "eslint",
              "bundler": "webpack"
            },
            "library": {
              "style": "css",
              "linter": "eslint"
            },
            "component": {
              "style": "css"
            }
          }
        }
      }
      ```
      
      ### Template 2: Project Configuration
      
      ```json
      // apps/web/project.json
      {
        "name": "web",
        "$schema": "../../node_modules/nx/schemas/project-schema.json",
        "sourceRoot": "apps/web/src",
        "projectType": "application",
        "tags": ["type:app", "scope:web"],
        "targets": {
          "build": {
            "executor": "@nx/webpack:webpack",
            "outputs": ["{options.outputPath}"],
            "defaultConfiguration": "production",
            "options": {
              "compiler": "babel",
              "outputPath": "dist/apps/web",
              "index": "apps/web/src/index.html",
              "main": "apps/web/src/main.tsx",
              "tsConfig": "apps/web/tsconfig.app.json",
              "assets": ["apps/web/src/assets"],
              "styles": ["apps/web/src/styles.css"]
            },
            "configurations": {
              "development": {
                "extractLicenses": false,
                "optimization": false,
                "sourceMap": true
              },
              "production": {
                "optimization": true,
                "outputHashing": "all",
                "sourceMap": false,
                "extractLicenses": true
              }
            }
          },
          "serve": {
            "executor": "@nx/webpack:dev-server",
            "defaultConfiguration": "development",
            "options": {
              "buildTarget": "web:build"
            },
            "configurations": {
              "development": {
                "buildTarget": "web:build:development"
              },
              "production": {
                "buildTarget": "web:build:production"
              }
            }
          },
          "test": {
            "executor": "@nx/jest:jest",
            "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
            "options": {
              "jestConfig": "apps/web/jest.config.ts",
              "passWithNoTests": true
            }
          },
          "lint": {
            "executor": "@nx/eslint:lint",
            "outputs": ["{options.outputFile}"],
            "options": {
              "lintFilePatterns": ["apps/web/**/*.{ts,tsx,js,jsx}"]
            }
          }
        }
      }
      ```
      
      ### Template 3: Module Boundary Rules
      
      ```json
      // .eslintrc.json
      {
        "root": true,
        "ignorePatterns": ["**/*"],
        "plugins": ["@nx"],
        "overrides": [
          {
            "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
            "rules": {
              "@nx/enforce-module-boundaries": [
                "error",
                {
                  "enforceBuildableLibDependency": true,
                  "allow": [],
                  "depConstraints": [
                    {
                      "sourceTag": "type:app",
                      "onlyDependOnLibsWithTags": [
                        "type:feature",
                        "type:ui",
                        "type:data-access",
                        "type:util"
                      ]
                    },
                    {
                      "sourceTag": "type:feature",
                      "onlyDependOnLibsWithTags": [
                        "type:ui",
                        "type:data-access",
                        "type:util"
                      ]
                    },
                    {
                      "sourceTag": "type:ui",
                      "onlyDependOnLibsWithTags": ["type:ui", "type:util"]
                    },
                    {
                      "sourceTag": "type:data-access",
                      "onlyDependOnLibsWithTags": ["type:data-access", "type:util"]
                    },
                    {
                      "sourceTag": "type:util",
                      "onlyDependOnLibsWithTags": ["type:util"]
                    },
                    {
                      "sourceTag": "scope:web",
                      "onlyDependOnLibsWithTags": ["scope:web", "scope:shared"]
                    },
                    {
                      "sourceTag": "scope:api",
                      "onlyDependOnLibsWithTags": ["scope:api", "scope:shared"]
                    },
                    {
                      "sourceTag": "scope:shared",
                      "onlyDependOnLibsWithTags": ["scope:shared"]
                    }
                  ]
                }
              ]
            }
          }
        ]
      }
      ```
      
      ### Template 4: Custom Generator
      
      ```typescript
      // tools/generators/feature-lib/index.ts
      import {
        Tree,
        formatFiles,
        generateFiles,
        joinPathFragments,
        names,
        readProjectConfiguration,
      } from "@nx/devkit";
      import { libraryGenerator } from "@nx/react";
      
      interface FeatureLibraryGeneratorSchema {
        name: string;
        scope: string;
        directory?: string;
      }
      
      export default async function featureLibraryGenerator(
        tree: Tree,
        options: FeatureLibraryGeneratorSchema,
      ) {
        const { name, scope, directory } = options;
        const projectDirectory = directory
          ? `${directory}/${name}`
          : `libs/${scope}/feature-${name}`;
      
        // Generate base library
        await libraryGenerator(tree, {
          name: `feature-${name}`,
          directory: projectDirectory,
          tags: `type:feature,scope:${scope}`,
          style: "css",
          skipTsConfig: false,
          skipFormat: true,
          unitTestRunner: "jest",
          linter: "eslint",
        });
      
        // Add custom files
        const projectConfig = readProjectConfiguration(
          tree,
          `${scope}-feature-${name}`,
        );
        const projectNames = names(name);
      
        generateFiles(
          tree,
          joinPathFragments(__dirname, "files"),
          projectConfig.sourceRoot,
          {
            ...projectNames,
            scope,
            tmpl: "",
          },
        );
      
        await formatFiles(tree);
      }
      ```
      
      ### Template 5: CI Configuration with Affected
      
      ```yaml
      # .github/workflows/ci.yml
      name: CI
      
      on:
        push:
          branches: [main]
        pull_request:
          branches: [main]
      
      env:
        NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
      
      jobs:
        main:
          runs-on: ubuntu-latest
          steps:
            - uses: actions/checkout@v4
              with:
                fetch-depth: 0
      
            - uses: actions/setup-node@v4
              with:
                node-version: 20
                cache: "npm"
      
            - name: Install dependencies
              run: npm ci
      
            - name: Derive SHAs for affected commands
              uses: nrwl/nx-set-shas@v4
      
            - name: Run affected lint
              run: npx nx affected -t lint --parallel=3
      
            - name: Run affected test
              run: npx nx affected -t test --parallel=3 --configuration=ci
      
            - name: Run affected build
              run: npx nx affected -t build --parallel=3
      
            - name: Run affected e2e
              run: npx nx affected -t e2e --parallel=1
      ```
      
      ### Template 6: Remote Caching Setup
      
      ```typescript
      // nx.json with Nx Cloud
      {
        "tasksRunnerOptions": {
          "default": {
            "runner": "nx-cloud",
            "options": {
              "cacheableOperations": ["build", "lint", "test", "e2e"],
              "accessToken": "your-nx-cloud-token",
              "parallel": 3,
              "cacheDirectory": ".nx/cache"
            }
          }
        },
        "nxCloudAccessToken": "your-nx-cloud-token"
      }
      
      // Self-hosted cache with S3
      {
        "tasksRunnerOptions": {
          "default": {
            "runner": "@nx-aws-cache/nx-aws-cache",
            "options": {
              "cacheableOperations": ["build", "lint", "test"],
              "awsRegion": "us-east-1",
              "awsBucket": "my-nx-cache-bucket",
              "awsProfile": "default"
            }
          }
        }
      }
      ```
      
      ## Common Commands
      
      ```bash
      # Generate new library
      nx g @nx/react:lib feature-auth --directory=libs/web --tags=type:feature,scope:web
      
      # Run affected tests
      nx affected -t test --base=main
      
      # View dependency graph
      nx graph
      
      # Run specific project
      nx build web --configuration=production
      
      # Reset cache
      nx reset
      
      # Run migrations
      nx migrate latest
      nx migrate --run-migrations
      ```
      
  • SKILL.md 2.2 KB
    ---
    name: nx-workspace-patterns
    description: Configure and optimize Nx monorepo workspaces. Use when setting up Nx, configuring project boundaries, optimizing build caching, or implementing affected commands.
    ---
    
    # Nx Workspace Patterns
    
    Production patterns for Nx monorepo management.
    
    ## When to Use This Skill
    
    - Setting up new Nx workspaces
    - Configuring project boundaries
    - Optimizing CI with affected commands
    - Implementing remote caching
    - Managing dependencies between projects
    - Migrating to Nx
    
    ## Core Concepts
    
    ### 1. Nx Architecture
    
    ```
    workspace/
    ├── apps/              # Deployable applications
    │   ├── web/
    │   └── api/
    ├── libs/              # Shared libraries
    │   ├── shared/
    │   │   ├── ui/
    │   │   └── utils/
    │   └── feature/
    │       ├── auth/
    │       └── dashboard/
    ├── tools/             # Custom executors/generators
    ├── nx.json            # Nx configuration
    └── workspace.json     # Project configuration
    ```
    
    ### 2. Library Types
    
    | Type            | Purpose                          | Example             |
    | --------------- | -------------------------------- | ------------------- |
    | **feature**     | Smart components, business logic | `feature-auth`      |
    | **ui**          | Presentational components        | `ui-buttons`        |
    | **data-access** | API calls, state management      | `data-access-users` |
    | **util**        | Pure functions, helpers          | `util-formatting`   |
    | **shell**       | App bootstrapping                | `shell-web`         |
    
    ## Templates and detailed worked examples
    
    Full template library and detailed worked examples live in `references/details.md`. Read that file when you need the concrete templates.
    
    ## Best Practices
    
    ### Do's
    
    - **Use tags consistently** - Enforce with module boundaries
    - **Enable caching early** - Significant CI savings
    - **Keep libs focused** - Single responsibility
    - **Use generators** - Ensure consistency
    - **Document boundaries** - Help new developers
    
    ### Don'ts
    
    - **Don't create circular deps** - Graph should be acyclic
    - **Don't skip affected** - Test only what changed
    - **Don't ignore boundaries** - Tech debt accumulates
    - **Don't over-granularize** - Balance lib count
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related