Skip to main content
Version: 6.0.0

dependencies

Enforce allowed dependencies between elements in your project.

Rule Details

This rule validates dependencies between elements in your project based on the provided configuration. It ensures that dependencies adhere to the defined architectural boundaries.

Options

"boundaries/dependencies":
[<enabled>, { "default": <string>, "message": <string>, "rules": <object> }]

Configuration properties:

  • enabled: Enables the rule. 0 = off, 1 = warning, 2 = error
  • default: "allow" or "disallow". Determines the default behavior for imports that don't match any rule
  • checkAllOrigins: Optional. Whether to check dependencies from all origins (including external and core) or only from local elements (default: false, only local).
  • checkUnknownLocals: Optional. Whether to check local dependencies with unknown elements (not matching any element descriptor) or to ignore them. (default: false)
  • checkInternals: Optional. Whether to check internal dependencies (dependencies within files in the same element) (default: false).
  • message: Custom error message for rule violations. Note that the default message provides detailed information about why the error occurred, so only define a custom message if necessary. See error messages for more information
  • rules: An array of rule objects processed in order to determine whether an import should be allowed. Each rule object can contain the following properties:
    • from: <element selector/s> - If the file being analyzed matches this selector, the rule will be evaluated. Otherwise, it is skipped
    • to: <element selector/s> - If the dependency target matches this selector, the rule will be evaluated. Otherwise, it is skipped
    • disallow: <dependency selector/s> - If the dependency matches this selector, it is disallowed (can be overridden by a subsequent rule returning "allow")
    • allow: <element selector/s> - If the dependency matches this selector, it is allowed (can be overridden by a subsequent rule returning "disallow")
    • message: <string> - Custom error message for this specific rule. See error messages for more information
    • importKind: <string> - Optional. Deprecated in v6 (kept for backward compatibility). Makes sense only for TypeScript projects. Use dependency.kind instead. If both are defined, dependency.kind takes precedence. Possible values: "value", "type", or "typeof". If defined, the rule will only be evaluated for dependencies of the specified kind.
warning

You must provide at least one of allow or disallow, and one of to or from for each rule.

Start checking external dependencies with this rule

The new checkAllOrigins option allows you to check dependencies from all origins (including external and core) instead of only checking dependencies between local known elements. This means that you can now use this rule to check and enforce boundaries for external dependencies as well, which was previously only possible with the deprecated boundaries/external rule. You can also use the new origin selector property in your rules to target specific origins (e.g., external, core, or local).

It is recommended to set checkAllOrigins to true and start defining rules for external dependencies in this rule instead of using the deprecated boundaries/external rule.

Using selectors in this rule

This rule uses element and dependency selectors to define which elements can depend on other elements.

For example: You can use element selector properties to ensure components of one type can only import helpers of the same type in the allow selector.

info

Read the rules configuration documentation to learn about how to use common rule options, use selectors in rule options, and customize error messages with templates.

tip

Enable debug mode in the plugin configuration to inspect the descriptions assigned to each file and dependency. This can help you understand how selectors are matching and how to configure your rules effectively.

Configuration Example

{
rules: {
"boundaries/dependencies": [2, {
// disallow all local imports by default
default: "disallow",
rules: [
{
// from helper elements
from: { type: "helper" },
// allow importing helper elements
allow: {
to: { type: "helper" },
// allow only importing value, not type (TypeScript only)
dependency: { kind: "value" }
},
},
{
// from component elements
from: { type: "component" },
allow: {
to: [
// allow importing components of the same family
{ type: "component", captured: { family: "{{ family }}" } },
// allow importing helpers with fileName "sort"
{ type: "helper", captured: { fileName: "sort" } }
]
}
},
{
// from components with captured family "molecule"
from: { type: "component", captured: { family: "molecule" } },
allow: {
// allow importing components with captured family "atom"
to: { type: "component", captured: { family: "atom" } }
}
},
{
// from modules
from: { type: "module" },
// allow importing helpers, components, and modules
allow: {
to: {
type: ["helper", "component", "module"]
}
}
}
]
}]
}
}

Settings

The following examples use this project structure and settings configuration.

Project structure:

src/
├── components/
│ ├── atoms/
│ │ ├── atom-a/
│ │ │ ├── index.js
│ │ │ └── AtomA.js
│ │ └── atom-b/
│ │ ├── index.js
│ │ └── AtomB.js
│ └── molecules/
│ ├── molecule-a/
│ │ ├── index.js
│ │ └── MoleculeA.js
│ └── molecule-b/
│ ├── index.js
│ └── MoleculeB.js
├── helpers/
│ ├── data/
│ │ ├── sort.js
│ │ └── parse.js
│ └── permissions/
│ └── roles.js
└── modules/
├── module-a/
│ ├── index.js
│ └── ModuleA.js
└── module-b/
├── index.js
└── ModuleB.js

Settings configuration:

{
settings: {
"boundaries/elements": [
{
type: "helper",
pattern: "helpers/*/*.js",
mode: "file",
capture: ["family", "elementName"]
},
{
type: "component",
pattern: "components/*/*",
mode: "folder",
capture: ["family", "elementName"]
},
{
type: "module",
pattern: "modules/*",
mode: "folder",
capture: ["elementName"]
}
],
"import/resolver": {
"babel-module": {}
}
}
}
note

These examples use aliases for the src/helpers, src/components, and src/modules folders. You can also use relative paths, or you can configure the plugin to recognize aliases by using resolvers.

Examples

Incorrect

Helpers importing components:

// src/helpers/permissions/roles.js
import AtomA from 'components/atoms/atom-a'

Helpers importing types from helpers:

// src/helpers/permissions/roles.js
import type { SomeParser } from 'helpers/data/parse'

Helpers importing modules:

// src/helpers/permissions/roles.js
import ModuleA from 'modules/module-a'

Components importing components from a different family:

// src/components/atoms/atom-a/AtomA.js
import MoleculeA from 'components/molecules/molecule-a'

Components importing helpers with a fileName different than "sort":

// src/components/atoms/atom-a/AtomA.js
import { roleHasPermissions } from 'helpers/permissions/roles'

Components importing modules:

// src/components/atoms/atom-a/AtomA.js
import ModuleA from 'modules/module-a'

Correct

Helpers importing helpers:

// src/helpers/permissions/roles.js
import { someParser } from 'helpers/data/parse'

Components importing components of the same family:

// src/components/atoms/atom-a/AtomA.js
import AtomB from 'components/atoms/atom-b'

Components importing helpers with fileName "sort":

// src/components/atoms/atom-a/AtomA.js
import { someSorter } from 'helpers/data/sort'

Molecule components importing atom components:

// src/components/molecules/molecule-a/MoleculeA.js
import AtomA from 'components/atoms/atoms-a'

Modules importing helpers:

// src/modules/module-a/ModuleA.js
import { someParser } from 'helpers/data/parse'

Modules importing components:

// src/modules/module-a/ModuleA.js
import AtomA from 'components/atoms/atom-a'

Modules importing other modules:

// src/modules/module-a/ModuleA.js
import ModuleB from 'modules/module-b'

Error Messages

This rule provides detailed error messages to help you understand and resolve violations.

  • No matching rule message: When no rule matches a dependency and the default behavior is "disallow", the message starts with:

    There is no rule allowing dependencies ...

    Then it describes briefly the elements involved in the dependency (e.g., from elements of type "component" and category "molecules" to elements of type "component" and category "atoms").

    Example:

    There is no rule allowing dependencies from elements of type "component" and category "molecules" to elements of type "module" and category "atoms"

  • Denied by rule message: When a rule matches and denies a dependency, the message describes the denied selector and ends with the rule index:

    ... . Denied by rule at index <n>

    Example:

    Dependencies to elements of type "component" and category "atoms" are not allowed in elements of type "helper". Denied by rule at index 1

    The exact sentence can vary depending on which selector parts where used to match the dependency (in any of from, to, dependency, disallow). For example, messages can include with module "...", with source "...", to elements of ..., and/or in elements of .... This detailed information in the messages is intended to help you understand exactly why a dependency is being disallowed and how to adjust your rules or code accordingly.

Custom Messages with Templates

tip

You can customize error messages globally or for specific rules. Use the message option in your rule configuration and see Rules Configuration -> Message Templating for more details.

Further Reading

Read next sections to learn more about related topics: