Settings Reference
This section provides a complete reference of all available global settings for the plugin.
boundaries/elements
Type: <array of element descriptors> - see Element Descriptors documentation
Required: No, but at least one classification layer must be configured — this setting or boundaries/files.
Defines element descriptors that recognize each file in the project as part of one of the defined elements. Rules need at least one classification layer to be configured: boundaries/elements, boundaries/files, or both.
export default [{
settings: {
"boundaries/elements": [
{ type: "helper", pattern: "helpers/*", capture: ["family"] },
{ type: "component", pattern: "components/*/*", capture: ["family", "elementName"] },
{ type: "module", pattern: "modules/*", capture: ["elementName"] }
]
}
}]
See the Element Descriptors section for every descriptor property, including pattern, type, capture, basePattern, and baseCapture.
boundaries/files
Type: <array of file descriptors> - see File Descriptors documentation
Default: []
Required: No, but it can be the only classification layer you configure instead of boundaries/elements.
Defines file descriptors that categorize files independently of the elements they belong to. The resulting categories appear at runtime as file.categories and can be matched in rule policies with the file selector and used in message templates (for example, {{to.file.categories}}). This is the recommended replacement for the deprecated element-descriptor category property.
export default [{
settings: {
"boundaries/files": [
{ pattern: "**/*.spec.js", category: "test" },
{ pattern: "**/*.css", category: "style" }
]
}
}]
See the Files section for the full reference, including how categories accumulate across matching descriptors and the migration from the deprecated element category property.
boundaries/elements-single-type
Type: <boolean>
Default: true (single-type, backward compatible)
Controls whether an element can have multiple types.
- When
true(default), each element keeps only the first matching descriptor's type. This matches the historical single-type behavior. - When
false, an element accumulates all descriptor types that match at the same path level, in descriptor order. The element'stypesarray then holds every matched type.
export default [{
settings: {
// Opt in to multi-type elements
"boundaries/elements-single-type": false
}
}]
The plugin defaults this setting to true (single-type) for backward compatibility. Set boundaries/elements-single-type: false to opt in to multi-type matching. See Multi-type Elements for an example and the accumulation rules.
boundaries/include
Type: <string | string[]>
Default: All files included
Files not matching these micromatch patterns will be ignored by the plugin.
export default [{
settings: {
"boundaries/include": ["src/**/*.js"]
}
}]
boundaries/ignore
Type: <string | string[]>
Default: No files ignored
Files matching these micromatch patterns will be ignored by the plugin.
export default [{
settings: {
"boundaries/ignore": ["**/*.spec.js", "src/legacy-code/**/*"]
}
}]
The boundaries/ignore option has precedence over boundaries/include. If you define boundaries/include, use boundaries/ignore to ignore subsets of included files.
boundaries/dependency-nodes
Type: <array of strings>
Default: ["import", "export", "require", "dynamic-import"]
Modifies which built-in dependency nodes are analyzed. By default, all of the following nodes are analyzed:
Available values:
'import'- Analyzeimportstatements'require'- Analyzerequirestatements'export'- Analyzeexportstatements'dynamic-import'- Analyze dynamic import statements (import())
All plugin rules will be applied to the nodes defined in this setting. Modify the default value only if you want to exclude some of the built-in dependency nodes from analysis.
export default [{
settings: {
"boundaries/dependency-nodes": ["import", "dynamic-import"]
}
}]
To check also custom dependency nodes (like jest.mock(...)), use boundaries/additional-dependency-nodes.
boundaries/additional-dependency-nodes
Type: <array of objects>
Default: []
Defines custom dependency nodes to analyze beyond the built-in ones. All plugin rules will be applied to nodes defined here in addition to the built-in ones defined in boundaries/dependency-nodes.
Object structure:
selector- The esquery selector for theLiteralnode where the dependency source is definedname(optional) - A name for the custom node, so you can use it in policy configuration usingdependency.nodeKind(e.g., to forbid or allow this kind of dependency node in some rules or to use it in custom messages templates variables)kind- Assigns thedependency.kindproperty in dependency descriptions, which you can use in policy configuration or custom message templates to target specific dependency kinds. Possible values are"value","type", or"typeof".
The name property is optional for the moment, but if you don't provide it, the plugin will not be able to identify the node kind of the dependency in policy configuration or custom messages templates, so it will be treated as a generic dependency without a specific node kind. If you want to use the custom node in policy configuration or custom messages templates, make sure to provide a unique name for it.
Example:
export default [{
settings: {
"boundaries/additional-dependency-nodes": [
// jest.requireActual('source')
{
selector: "CallExpression[callee.object.name=jest][callee.property.name=requireActual] > Literal",
name: "jest-require-actual",
kind: "value"
},
// jest.mock('source', ...)
{
selector: "CallExpression[callee.object.name=jest][callee.property.name=mock] > Literal:first-child",
name: "jest-mock",
kind: "value"
},
],
}
}]
boundaries/root-path
Type: <string>
Default: process.cwd()
Defines the root path of the project. By default, the plugin uses the current working directory.
When to use: This setting is useful when executing the lint command from a different path than the project root, which may otherwise produce unexpected results when matching basePattern in element descriptors or classifying module origins.
Example with ESM:
import { resolve } from "node:path";
export default [{
settings: {
"boundaries/root-path": resolve(import.meta.dirname)
}
}]
Using environment variable:
ESLINT_PLUGIN_BOUNDARIES_ROOT_PATH=../../project-root npm run lint
You can provide either an absolute path or a relative path to the project root in the environment variable. Relative paths will be resolved from where the lint command is executed.
The path should be absolute and resolved before passing it to the plugin. Otherwise, it will be resolved using the current working directory.
Matching patterns in element descriptors are relative to the rootPath. The plugin automatically converts absolute file paths to relative paths internally for pattern matching. Depending on the element descriptor's partialMatch property, patterns are evaluated right-to-left (from the end of the path) or not, and then, the relativity to rootPath is less or more critical. Read the Element Descriptors section for more details on how partialMatch affects pattern matching.
The rootPath setting may affect the module origin assigned to dependencies resolved outside the root path, classifying them as "external" or "local". You can customize this behavior with the boundaries/flag-as-external setting. See Modules → How settings influence origin for the full effect.
boundaries/cache
Type: <boolean>
Default: true
Enables or disables the cache mechanism used to boost performance.
export default [{
settings: {
"boundaries/cache": true // or false to disable
}
}]
Recommendation: Keep cache enabled unless you experience issues. If you encounter problems, please open a github issue describing them.
boundaries/flag-as-external
Type: <object>
Default:
{
unresolvableAlias: true,
inNodeModules: true,
outsideRootPath: false,
customSourcePatterns: []
}
Defines custom rules for categorizing a dependency's module origin as external or local. By default, the plugin categorizes dependencies in node_modules and unresolvable imports as external. Use this setting to customize this behavior. See Modules → How settings influence origin for how each condition affects the resulting origin.
This setting is especially useful in monorepo environments. Read the Monorepo Setup guide for detailed examples of different monorepo configurations using this setting.
Object properties:
unresolvableAlias<boolean>- Iftrue, non-relative imports that cannot be resolved are categorized as external. Default:trueinNodeModules<boolean>- Iftrue, imports resolved to paths containingnode_modulesare categorized as external. Default:trueoutsideRootPath<boolean>- Iftrue, imports resolved to paths outside the configuredroot-pathare categorized as external. Default:falsecustomSourcePatterns<array of strings>- Import sources matching any of these micromatch patterns are categorized as external. Default:[]
All conditions are evaluated with OR logic: a dependency is categorized as external if any of the enabled conditions is met.
Example - Treat inter-package imports as external in a monorepo:
import { resolve } from "node:path";
export default [{
files: ["packages/app/**/*.js"],
settings: {
"boundaries/root-path": resolve(import.meta.dirname, "packages/app"),
"boundaries/flag-as-external": {
outsideRootPath: true // Imports outside packages/app have `external` origin
}
}
}]
Example - Treat specific import patterns as external:
export default [{
files: ["packages/**/*.js"],
settings: {
"boundaries/flag-as-external": {
customSourcePatterns: ["@myorg/*", "~/**"]
// Organization packages are considered external
}
}
}]
Example - Treat all resolved imports as local, even if outside rootPath (for granular boundary rules between packages):
export default [{
files: ["packages/**/*.js"],
settings: {
"boundaries/flag-as-external": {
unresolvableAlias: true, // Still treat unresolvable as external
inNodeModules: true, // npm packages remain external
outsideRootPath: false, // Inter-package imports are local, even if outside rootPath
customSourcePatterns: [] // No custom patterns
}
}
}]
See the Monorepo Setup Guide for detailed examples of different monorepo configurations.
import/resolver
Type: <object>
Configures custom module resolution for the plugin, leveraging the same resolver infrastructure used by eslint-plugin-import (through the eslint-module-utils/resolve module), giving you access to a wide ecosystem of resolvers for different project setups.
Read more about configuring custom resolvers in the Custom Resolvers guide.
export default [{
settings: {
"import/resolver": {
webpack: {
config: "webpack.config.js"
}
}
}
}];
boundaries/debug
Type: <object>
Default:
{
enabled: false,
messages: {
files: true,
dependencies: true,
violations: true,
},
filter: {
files: undefined,
dependencies: undefined,
}
}
Enables debug traces and optionally filters them with selectors. When enabled, debug prints the full runtime entity description (element, file, and module) for each analyzed file.
enabled<boolean>- Enables debug output whentrue. Defaultfalse. Debug also turns on via theESLINT_PLUGIN_BOUNDARIES_DEBUGenvironment variable.messages<object>- Configures which message types to print (file descriptions, dependency descriptions, and policy violation descriptions). All are enabled by default.files<boolean>- Prints file descriptions for each file analyzed.dependencies<boolean>- Prints dependency descriptions for each dependency analyzed.violations<boolean>- Prints policy violation descriptions for each rule policy violation detected.
filter<object>- Configures filters to apply to debug traces. See the sub-properties for the accepted selector types. By default, no filters are applied, and all debug traces are printed when debug mode is enabled.filter.files- Filters file traces. Accepts both file selectors and entity selectors (an array means OR).filter.dependencies- Filters dependency traces. Accepts dependency selectors —{ from?, to?, dependency? }objects (an array means OR).
You can filter debug traces using selectors. See the Debugging guide for complete filtering examples.
boundaries/legacy-templates
Type: <boolean>
Default: true (will be false in a future major version)
Whether to prioritize the legacy ${} template syntax in selectors over the Handlebars {{}} syntax.
When true, captured values are injected at the top level of the template data, so they take precedence over the built-in legacy aliases. There is a risk of conflict if you name a captured value the same as one of those aliases: type, elementPath, internalPath, origin, or parents. Set this to false to avoid the risk and use the Handlebars syntax in all your templates. Old templates keep working without changes regardless of this setting.
This setting only affects selectors. It does not change the syntax available in custom message templates: the legacy syntax there does not expose the Handlebars variables, so it keeps working as-is, while new templates can use the full Handlebars data tree.
Read more about legacy templates in the Legacy Message Templates section.
boundaries/legacy-warnings
Type: <boolean>
Default: true
When false, skips all legacy-pattern detection work and suppresses the associated runtime deprecation warnings, reducing overhead at lint time. Turn it off in case you don't want to see the warnings anymore, or to improve performance (but be aware to activate it again before you upgrade to a future major version, as some legacy patterns will be removed).
export default [{
settings: {
"boundaries/legacy-warnings": false
}
}]
Deprecated Settings
The boundaries/types and boundaries/alias settings are kept for backward compatibility but are deprecated. Use boundaries/elements and the import/resolver settings instead. They are documented, with migration guidance, on the Deprecated Settings page.
Next Steps
- Elements - element descriptors in context.
- Files - file descriptor properties and category accumulation.
- Selectors - the selectors used by policies and debug filters.
- Policies - message templates referenced by
legacy-templates. - Debugging - debug filter examples.
- Monorepo Setup -
flag-as-externalusage in monorepos.