@nx-devkit/boundaries
v0.0.12
Published
Linter-agnostic Nx plugin: enforces module-boundary depConstraints between tagged projects — no ESLint, no project.json required.
Maintainers
Readme
@nx-devkit/boundaries
Linter-agnostic Nx plugin: enforces module-boundary depConstraints between tagged projects — the @nx/enforce-module-boundaries idea, without requiring ESLint. Works alongside oxlint, Biome, or no linter at all.
Part of nx-devkit.
Install
bun add -D @nx-devkit/boundariesDepends on @nx/devkit ^22 || ^23 (installed automatically — nx itself comes from your workspace via devkit's peer range) and typescript >=5 (the import scanner uses the TS parser).
Register
nx add @nx-devkit/boundaries # runs the init generator — registers the plugin in nx.jsonOr manually:
// nx.json
{
"plugins": [
{
"plugin": "@nx-devkit/boundaries",
"options": {
"depConstraints": [
{ "sourceTag": "type:app", "onlyDependOnLibsWithTags": ["type:feature", "type:util"] },
{ "sourceTag": "type:feature", "onlyDependOnLibsWithTags": ["type:util"] }
]
}
}
]
}Tag your projects
Tags live in each package's package.json — no project.json required:
{ "name": "@acme/web", "nx": { "tags": ["type:app"] } }Nx merges nx.* metadata into the project whether it was inferred or declared, so nx show project displays the tags identically.
What it does
- Infers one
check-boundariestarget on the workspace root — only when at least one project declaresnx.tags(a tagless workspace would be a false green). - The executor loads the project graph, scans each tagged project's sources with the TypeScript parser (
import,export ... from,import(),require()— comments and strings can't produce false positives), resolves specifiers to workspace projects (relative paths, package names, tsconfigpaths), and evaluatesdepConstraints. - Violations print
file:line — source (tags) cannot depend on target (tags) via "specifier"and fail the target.
Semantics match the official rule: constraints apply when sourceTag matches the importing project's tags; the target must share a tag with onlyDependOnLibsWithTags; untagged sources are permissive; self-imports are always allowed. Tag patterns support wildcards — * matches any project carrying at least one tag, and partial globs like scope:* expand *; in onlyDependOnLibsWithTags, * means "the target must be tagged".
Run
npx nx check-boundaries # or: npx nx run <root>:check-boundaries
npx nx affected -t check-boundariesOptions
| Option | Default | Description |
|---|---|---|
| depConstraints | [] | [{ sourceTag, onlyDependOnLibsWithTags }] — same shape as the official rule |
| targetName | check-boundaries | Inferred target name on the root project |
Non-goals (v1)
- No circular-dependency detection
- No npm/external-package constraints (
bannedExternalImports) - No auto-fix
License
MIT
