@lapidix/eslint-plugin-boundaries
v0.1.1
Published
ESLint plugin to enforce architectural boundaries and public API imports.
Maintainers
Readme
@lapidix/eslint-plugin-boundaries
ESLint plugin to enforce architectural boundaries and public API imports.
Works with any layered architecture:
- Feature-Sliced Design (FSD)
- Clean Architecture
- Hexagonal Architecture
- Atomic Design
- Custom structures
Installation
npm install -D @lapidix/eslint-plugin-boundariesPeer Dependencies
npm install -D eslint @typescript-eslint/parser eslint-plugin-boundariesQuick Start
// eslint.config.mjs
import boundaries from "@lapidix/eslint-plugin-boundaries";
const config = boundaries.createConfig({
allowOneDepth: true, // Allow 1-depth sub-modules with index.ts
});
export default [
// ... your other configs
{
plugins: {
"@lapidix/boundaries": boundaries,
},
},
...config,
];Configuration Options
createConfig(options)
| Option | Type | Default | Description |
| ----------------- | ------------------------ | ---------------------------------- | ------------------------------ |
| preset | "strict" \| "extended" | "strict" | Base preset |
| allowOneDepth | boolean | false | Allow any 1-depth sub-module |
| layers | string[] | FSD layers | Custom layer hierarchy |
| subModules | string[] | [] | Additional allowed sub-modules |
| alias | object | { prefix: "@/", baseDir: "src" } | Alias configuration |
| ignoreTestFiles | boolean | true | Ignore test files |
| testPatterns | string[] | Common patterns | Custom test file patterns |
Layer Presets
import { LAYER_PRESETS } from "@lapidix/eslint-plugin-boundaries";
// Feature-Sliced Design (default)
createConfig({ layers: LAYER_PRESETS.fsd });
// Clean Architecture
createConfig({ layers: LAYER_PRESETS.clean });
// Hexagonal Architecture
createConfig({ layers: LAYER_PRESETS.hexagonal });
// Atomic Design
createConfig({ layers: LAYER_PRESETS.atomic });
// Common Frontend
createConfig({ layers: LAYER_PRESETS.frontend });
// React/Next.js
createConfig({ layers: LAYER_PRESETS.react });
// Vue.js
createConfig({ layers: LAYER_PRESETS.vue });Rules
@lapidix/boundaries/enforce-public-api
Enforces that imports only access public APIs (modules with index.ts).
// ✅ Good - accessing public API
import { User } from "@/entities/user";
import { Button } from "@/shared/ui";
// ❌ Bad - accessing internal module
import { User } from "@/entities/user/model/user.entity";@lapidix/boundaries/no-same-layer-alias
Enforces relative imports within the same layer.
// ✅ Good - relative import for same layer
import { useUser } from "../../user/hooks";
// ❌ Bad - alias import for same layer
import { useUser } from "@/features/user/hooks";@lapidix/boundaries/prefer-alias-import
Enforces alias imports when crossing layer boundaries.
// ✅ Good - alias import for different layer
import { User } from "@/entities/user";
// ❌ Bad - relative import crossing layers
import { User } from "../../../entities/user";@lapidix/boundaries/require-public-api
Warns when a module is missing an index.ts file.
Examples
FSD (Feature-Sliced Design)
createConfig({
allowOneDepth: true,
// Uses default FSD layers:
// ['shared', 'entities', 'features', 'widgets', 'pages', 'app']
});Clean Architecture
createConfig({
allowOneDepth: true,
layers: ["domain", "application", "infrastructure", "presentation"],
});Custom Configuration
createConfig({
preset: "extended",
layers: ["core", "services", "ui"],
subModules: ["components", "hooks", "utils"],
alias: { prefix: "~/", baseDir: "app" },
ignoreTestFiles: true,
});Auto-fix
Some rules support auto-fix:
eslint --fix .no-same-layer-alias: Converts alias to relative pathprefer-alias-import: Converts relative path to alias
License
MIT
