@sashar/eslint-plugin-fsd-paths
v1.0.1
Published
ESLint plugin for checking the correctness of import paths in FSD architecture
Maintainers
Readme
eslint-plugin-fsd-paths
ESLint plugin for enforcing import path rules in Feature‑Sliced Design (FSD) projects. Keeps import paths consistent: relative imports inside a slice, public API usage between slices, and correct layer ordering.
Requirements
- Project structure:
src/{app,pages,widgets,features,entities,shared} aliasshould be provided without a trailing slash, e.g.@
Installation
Install ESLint (if not already):
npm install --save-dev eslintInstall the plugin:
npm install --save-dev @sashar/eslint-plugin-fsd-pathsUsage
Add the plugin and rules to your ESLint config (example .eslintrc.js):
module.exports = {
plugins: ['@sashar/fsd-paths'],
rules: {
// 1. Relative imports within the same slice
'@sashar/fsd-paths/path-checker': ['error', { alias: '@' }],
// 2. Public API entry-point imports
'@sashar/fsd-paths/public-api-imports': ['error', {
alias: '@',
testFilesPatterns: ['**/*.test.*', '**/*.spec.*']
}],
// 3. Layered import order (app → pages → widgets → features → entities → shared)
'@sashar/fsd-paths/layer-imports': ['error', {
alias: '@',
ignoreImportPatterns: ['**/styles/**', '**/StoreProvider']
}]
}
};Rules
1. path-checker
Purpose: Ensure imports within the same feature slice use relative paths.
Option: alias (string) — your project alias (e.g. "@").
Valid:
// same slice, relative
import { helper } from '../model/helper';Invalid:
// deep or absolute import within slice
import { helper } from '@/features/MyFeature/model/helper';Auto-fix:
Running ESLint with --fix will convert deep absolute imports into relative ones.
2. public-api-imports
Purpose: Enforce imports from other slices go through the public API (index.ts). Test files may import from testing.ts.
Options:
alias(string)testFilesPatterns(string[]) — glob patterns for test files
Valid:
// public API
import { getUser } from '@/entities/User';
// testing API in test files
import { mockUser } from '@/entities/User/testing';Invalid:
// deep import outside index.ts
import { api } from '@/entities/User/model/api'; // ✕
// testing API import in non-test file
import { mock } from '@/entities/User/testing'; // ✕Auto-fix:
--fix will replace deep imports with the public API import, e.g. @/entities/User.
3. layer-imports
Purpose: Enforce allowed import directions between layers.
Allowed flow:
app → pages → widgets → features → entities → sharedOptions:
alias(string)ignoreImportPatterns(string[]) — glob patterns to skip
Examples — allowed:
// features → entities
import { Article } from '@/entities/Article';
// entities → shared
import { Button } from '@/shared/ui/Button';
// entities → entities (different slice)
import { Comment } from '@/entities/Comment';
// shared → shared
import { logger } from '@/shared/lib/logger';Note: Cross-slice imports inside the same layer are allowed only for
entitiesandshared.
Invalid example:
// entities → features (not allowed)
import { AuthForm } from '@/features/Auth';Recommendations
- Use an alias (e.g.
@) to avoid conflicts withnode_modules. - Configure
testFilesPatternsto match your test files (Jest, Vitest, etc.). - Add
ignoreImportPatternsfor styles or special provider modules that should be excluded from checks.
CLI
Run ESLint for a file:
npx eslint path/to/file.tsRun with auto-fix:
npx eslint --fix path/to/file.ts