Skip to main content
Version: 7.0.0

entry-point

Enforce entry point restrictions for elements in your project.

Deprecated

boundaries/entry-point is kept for backward compatibility but is deprecated and will be removed in a future major version. Use boundaries/dependencies instead.

It keeps working without changes; you will see a deprecation warning in your console:

Rule "boundaries/entry-point" is deprecated and will be removed in future versions. Please migrate to the "boundaries/dependencies" rule with appropriate selectors.

Read the migration guide below for conversion examples, and the v6 to v7 migration guide for the full picture.

Same base mechanism as Policies

This rule builds on the same base configuration documented in Policies (a default plus a rules array). The differences are: its rule entries use a required target entity selector (an alias of to) instead of from/to, and the policy allow/disallow values match the imported fileInternalPath entry points. Read Policies first, then the options below for the differences.

Rule Details

This rule validates dependencies to ensure that each element is imported only through its defined entry point. Files that are not declared as entry points cannot be imported from other elements.

Options

"boundaries/entry-point":
[<severity>, { "default": <string>, "message": <string>, "rules": <object> }]

The first item in the array is the ESLint severity (0 = off, 1 = warning, 2 = error). The second item is the options object:

  • default: "allow" or "disallow". Determines the default behavior for imports that don't match any policy rule. If "allow", imports are allowed unless explicitly disallowed by a rule. If "disallow", imports are disallowed unless explicitly allowed by a policy.
  • 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 policy objects processed in order to determine whether an import should be allowed. Each policy object can have the following properties:
    • target (required): <entity selectors> - The policy is only evaluated when the imported element matches this selector. Accepts both legacy element selectors (for example { type: "module" }) and entity selectors (for example { element: { type: "module" } }).
    • disallow: <string> - A micromatch pattern. If the imported file path matches this pattern, the import is disallowed (can be overridden by a subsequent rule returning "allow"). The pattern is matched against the fileInternalPath — the imported file's path relative to its element root (for example index.js or subfolder/main.js)
    • allow: <string> - A micromatch pattern. If the imported file path matches this pattern, the import is allowed (can be overridden by a subsequent rule returning "disallow"). Like disallow, the pattern is matched against the fileInternalPath
    • importKind: <string> - Optional. Makes sense when using TypeScript only. If defined, the policy is only evaluated for dependencies of the specified kind. Possible values: "value", "type", or "typeof"
    • message: <string> - Custom error message for this specific policy. See error messages for more information
warning

Each policy requires target and at least one of allow or disallow.

Deprecated

The policy-level importKind option is deprecated. When you migrate to boundaries/dependencies, replace it with the dependency.kind selector property. See the v6 to v7 migration guide for details.

info

Read the policies documentation to learn about how to use common policy options, use selectors in policy 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/entry-point": [2, {
// disallow all entry points by default
default: "disallow",
policies: [
{
// when importing helpers
target: { type: "helper" },
// allow importing any file from a helper element
allow: "*"
},
{
// when importing components or modules
target: {
type: [
"component",
"module"
]
},
// only allow index.js
allow: "index.js",
// allow only importing values, not types (TypeScript only)
// note: importKind is deprecated, use dependency.kind after migrating
importKind: "value"
}
]
}]
}
}

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/*",
capture: ["family"]
},
{
type: "component",
pattern: "components/*/*",
capture: ["family", "elementName"]
},
{
type: "module",
pattern: "modules/*",
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. You can configure the plugin to recognize aliases by using resolvers.

Examples

Incorrect

Importing files other than index.js from components:

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

Importing files other than index.js from modules:

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

Importing types from module entry points:

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

Correct

Importing helper files:

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

Importing index.js from components:

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

Explicitly importing index.js from components:

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

Importing index.js from 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.

It uses the same default message format as boundaries/dependencies. The message includes information about the violated rule and the elements involved in the violation, as well as the internal path of the imported file.

For example:

Dependencies to elements of type "module", captured values: elementName="module-a" and fileInternalPath "ModuleA.js" are not allowed. Denied by rule at index 1

Custom Messages with Templates

tip

You can customize error messages globally or for specific rules. See Rules Configuration -> Message Templating for more details.

Migration to boundaries/dependencies

The entry point restrictions enforced by this rule can also be achieved with the boundaries/dependencies rule. There, you select the target element with to, and constrain the importable files with the fileInternalPath property of the element sub-selector.

The following example shows how to migrate a configuration from boundaries/entry-point to boundaries/dependencies. The legacy target becomes to, and allow: "index.js" becomes a policy that allows only files whose fileInternalPath matches index.js. The deprecated importKind option becomes dependency.kind:

{
rules: {
"boundaries/entry-point": [2, {
"boundaries/dependencies": [2, {
default: "disallow",
policies: [
{
target: ["component", "module"],
allow: "index.js",
importKind: "value"
}
{
to: { element: { type: ["component", "module"] } },
allow: {
to: { element: { fileInternalPath: "index.js" } }
},
dependency: { kind: "value" }
}
]
}]
}
}

Read more about entity selectors and the fileInternalPath property in the Selectors documentation, and see the v6 to v7 migration guide for the complete migration.

Bonus: Allowing different entry points based on the importer element

With boundaries/dependencies you can also define rules to allow different entry points depending on the importer element, which was not possible with the entry-point rule. For example, you could allow importing index.js from components but only allow importing main.js from modules.

Further Reading

Learn more about related topics:

  • Defining Elements - Learn how to define architectural elements in your project
  • Selectors - Learn how to use element, file, and module selectors (the target option accepts entity selectors)
  • Policies - Learn how to configure common rule options
  • Global Settings - Learn about global settings that affect all rules
  • Migrating from v6 to v7 - Migrate deprecated rules to boundaries/dependencies