Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nrwl/nx/llms.txt

Use this file to discover all available pages before exploring further.

As a monorepo grows, unrestricted dependencies between projects lead to a tangled architecture that becomes difficult to maintain. Nx provides a tag-based constraint system that lets you define and automatically enforce which projects are allowed to depend on each other.

Two approaches

Nx supports two complementary approaches:

ESLint (JS/TS projects)

Enforces boundaries on TypeScript imports and package.json dependencies during linting with the @nx/enforce-module-boundaries rule.

Conformance (any language)

Enforces boundaries on the full Nx project graph using nx conformance:check. Works for Java, Python, PHP, and any other project type. Requires Nx Enterprise.
Both approaches use the same tag-based constraint system.

Step 1: Tag your projects

Add tags to each project’s configuration. Tags are arbitrary strings — a common convention is to use prefixes like scope: or type:.
// client/project.json
{
  "tags": ["scope:client"]
}
// admin/project.json
{
  "tags": ["scope:admin"]
}
// utils/project.json
{
  "tags": ["scope:shared"]
}

Step 2: Configure boundary rules

Install the plugin:
nx add @nx/eslint-plugin @nx/devkit
Configure the rule in eslint.config.mjs:
// eslint.config.mjs
import nx from '@nx/eslint-plugin';

export default [
  ...nx.configs['flat/base'],
  ...nx.configs['flat/typescript'],
  ...nx.configs['flat/javascript'],
  {
    files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
    rules: {
      '@nx/enforce-module-boundaries': [
        'error',
        {
          allow: [],
          depConstraints: [
            {
              sourceTag: 'scope:shared',
              onlyDependOnLibsWithTags: ['scope:shared'],
            },
            {
              sourceTag: 'scope:admin',
              onlyDependOnLibsWithTags: ['scope:shared', 'scope:admin'],
            },
            {
              sourceTag: 'scope:client',
              onlyDependOnLibsWithTags: ['scope:shared', 'scope:client'],
            },
          ],
        },
      ],
    },
  },
];
With these rules in place:
  • scope:shared can only depend on other scope:shared projects
  • scope:admin can depend on scope:admin and scope:shared
  • scope:client can depend on scope:client and scope:shared
  • scope:client and scope:admin cannot depend on each other
Violations produce a lint error:
A project tagged with "scope:admin" can only depend on projects
tagged with "scope:shared" or "scope:admin".

Tag format reference

{
  "sourceTag": "scope:client",
  "onlyDependOnLibsWithTags": ["scope:util"]
}
Allow any project to depend on any other project:
{
  "sourceTag": "*",
  "onlyDependOnLibsWithTags": ["*"]
}
{
  "sourceTag": "scope:client",
  "onlyDependOnLibsWithTags": ["/^scope.*/"]
}
{
  "sourceTag": "scope:*",
  "onlyDependOnLibsWithTags": ["scope:*"]
}
Glob supports * only. Use regex for more complex patterns.
Projects without any tags cannot depend on any other projects by default. You must explicitly allow them using the "*" wildcard, or add tags to those projects.