eslint-plugin-fsd-lint v1.0.6
π eslint-plugin-fsd-lint π
It supports ESLint 9+ and the new Flat Config system.
π Introduction
eslint-plugin-fsd-lint
is an ESLint plugin that enforces best practices for Feature-Sliced Design (FSD) architecture.
It is fully compatible with ESLint 9+ and follows the modern Flat Config format, ensuring seamless integration into modern JavaScript and TypeScript projects.
β¨ Why use this plugin?
- Flat Config support: Fully compatible with ESLint 9+ and the new Flat Config system.
- Strict FSD compliance: Prevents architectural violations in feature-based project structures.
- Improves maintainability: Encourages clear module separation and dependency control.
- Ensures consistent code quality: Standardizes import patterns and best practices.
π What is Feature-Sliced Design?
Feature-Sliced Design (FSD) is a modern architecture pattern that provides a structured approach to organizing frontend applications.
This plugin enforces key FSD principles such as proper layer separation, import restrictions, and dependency management,
helping developers build scalable and maintainable codebases.
π¦ Installation
You can install eslint-plugin-fsd-lint
via npm or pnpm:
Using npm:
npm install --save-dev eslint-plugin-fsd-lint
Using pnpm:
pnpm add -D eslint-plugin-fsd-lint
Peer Dependencies
This plugin requires ESLint 9+ to work properly.
Make sure you have ESLint installed in your project:
npm install --save-dev eslint
π‘ Tip: If you're using a monorepo with multiple packages, install eslint-plugin-fsd-lint at the root level to share the configuration across all workspaces.
π Usage & Configuration
π§ Flat Config Setup (eslint.config.mjs
)
eslint-plugin-fsd-lint
is designed for ESLint 9+ and works seamlessly with the Flat Config system.
To use it in your project, add the following configuration to your eslint.config.mjs
:
import fsdPlugin from "eslint-plugin-fsd-lint";
export default [
{
plugins: {
fsd: fsdPlugin,
},
rules: {
"fsd/forbidden-imports": "error",
"fsd/no-relative-imports": "error",
"fsd/no-public-api-sidestep": "error",
"fsd/no-cross-slice-dependency": "error",
"fsd/no-ui-in-business-logic": "error",
"fsd/no-global-store-imports": "error",
"fsd/ordered-imports": "warn"
},
},
];
π Recommended Configurations
For a stricter FSD enforcement, you can extend the default rule set:
import fsdPlugin from "eslint-plugin-fsd-lint";
export default [
{
plugins: {
fsd: fsdPlugin,
},
rules: {
"fsd/forbidden-imports": "error",
"fsd/no-relative-imports": "error",
"fsd/no-public-api-sidestep": "error",
"fsd/no-cross-slice-dependency": "error",
"fsd/no-ui-in-business-logic": "error",
"fsd/no-global-store-imports": "error",
"fsd/ordered-imports": "error"
},
},
];
π Example Project Structure
Hereβs how an FSD-compliant project might look:
src/
βββ app/
β βββ providers/
β βββ store.js
β βββ index.js
β
βββ processes/
β βββ auth/
β βββ onboarding/
β
βββ pages/
β βββ HomePage/
β βββ ProfilePage/
β
βββ widgets/
β βββ Navbar/
β βββ Sidebar/
β
βββ features/
β βββ login/
β βββ registration/
β
βββ entities/
β βββ user/
β βββ post/
β
βββ shared/
β βββ ui/
β βββ utils/
π‘ Tip: The plugin enforces correct layer imports according to FSD principles. For example, a feature can depend on entities and shared, but cannot directly import another feature.
Relative imports are allowed only within the same slice, but must be avoided across different slices or layers.
π Supported Rules
This plugin provides a set of ESLint rules that enforce Feature-Sliced Design (FSD) best practices. Each rule helps maintain a clear module structure, enforce import constraints, and prevent architectural violations.
Rule | Description |
---|---|
fsd/forbidden-imports | Prevents imports from higher layers and cross-imports between slices. |
fsd/no-relative-imports | Disallows relative imports across different slices or layers. Allows relative imports within the same slice. |
fsd/no-public-api-sidestep | Prevents direct imports from internal modules, enforcing public API usage. |
fsd/no-cross-slice-dependency | Disallows direct dependencies between feature slices. |
fsd/no-ui-in-business-logic | Prevents UI imports inside business logic layers (e.g., entities ). |
fsd/no-global-store-imports | Forbids direct imports of global state (store ). |
fsd/ordered-imports | Enforces import grouping by layer. |
π Rule Details & Examples
1οΈβ£ fsd/forbidden-imports
Prevents imports from higher layers and cross-imports between slices.
β
Allowed: features
can import from entities
or shared
β Not Allowed: features
importing directly from app
// β Incorrect (feature importing from app)
import { config } from "../../app/config";
// β
Correct (feature importing from entities/shared)
import { getUser } from "../../entities/user";
import { formatCurrency } from "../../shared/utils";
2οΈβ£ fsd/no-relative-imports
Disallows relative imports and enforces alias usage. β Allowed: Using project-defined aliases β Not Allowed: Using ../ or ./
// β Incorrect (relative import across different slices)
import { fetchUser } from "../another-slice/model/api";
// β
Correct (relative import within the same slice)
import { fetchData } from "../model/api";
// β
Correct (alias import across slices or layers)
import { Button } from "@shared/ui/Button";
3οΈβ£ fsd/no-public-api-sidestep
Prevents direct imports from internal modules of features, widgets, or entities. β Allowed: Importing from index.ts (public API) β Not Allowed: Importing a featureβs internal file
// β Incorrect (direct internal import)
import { authSlice } from "../../features/auth/slice.ts";
// β
Correct (importing via public API)
import { authSlice } from "../../features/auth";
4οΈβ£ fsd/no-cross-slice-dependency
Prevents direct dependencies between feature slices. β Allowed: features should communicate via entities or shared β Not Allowed: Direct imports between different features
// β Incorrect (feature importing from another feature)
import { processPayment } from "../../features/payment";
// β
Correct (using entities/shared as an intermediary)
import { PaymentEntity } from "../../entities/payment";
5οΈβ£ fsd/no-ui-in-business-logic
Prevents UI imports inside business logic layers (e.g., entities). β Allowed: UI should only be used inside widgets or pages β Not Allowed: entities importing UI components
// β Incorrect (entity importing widget)
import { ProfileCard } from "../../widgets/ProfileCard";
// β
Correct (widget using entity data)
import { getUser } from "../../entities/user";
6οΈβ£ fsd/no-global-store-imports
Forbids direct imports of global state (store). β Allowed: Using useStore or useSelector β Not Allowed: Direct imports of the store
// β Incorrect (direct import of store)
import { store } from "../../app/store";
// β
Correct (using hooks)
import { useStore } from "zustand";
import { useSelector } from "react-redux";
7οΈβ£ fsd/ordered-imports
Enforces import grouping by layer. β Allowed: Grouping imports by layer β Not Allowed: Mixed import order
// β Incorrect (random import order)
import { processPayment } from "../features/payment";
import { getUser } from "../entities/user";
import { formatCurrency } from "../shared/utils";
import { loginUser } from "../features/auth";
import { Header } from "../widgets/Header";
import { useStore } from "../app/store";
// β
Correct (layered grouping)
import { useStore } from "../app/store"; // App
import { loginUser } from "../features/auth"; // Features
import { processPayment } from "../features/payment";
import { getUser } from "../entities/user"; // Entities
import { formatCurrency } from "../shared/utils"; // Shared
import { Header } from "../widgets/Header"; // Widgets
π‘ Tip: Use
npx eslint --fix
to automatically reorder imports according to FSD layers.
π Auto-fix Support
Certain rules in eslint-plugin-fsd-lint
support automatic fixing using ESLint's --fix
option.
This allows developers to quickly resolve violations without manual code adjustments.
β Rules Supporting Auto-fix
The following rules can be automatically fixed:
Rule | Description |
---|---|
fsd/ordered-imports | Automatically sorts imports based on Feature-Sliced Design (FSD) layers. |
π§ Using --fix
in ESLint
To apply automatic fixes to your project, simply run:
npx eslint --fix your-file.js
Or, to fix all files in your project:
npx eslint --fix .
π Example Before & After Auto-fix
β Before (fsd/ordered-imports violation)
import { processPayment } from "../features/payment";
import { getUser } from "../entities/user";
import { formatCurrency } from "../shared/utils";
import { loginUser } from "../features/auth";
import { Header } from "../widgets/Header";
import { useStore } from "../app/store";
β After (npx eslint --fix applied)
import { useStore } from "../app/store"; // App
import { loginUser } from "../features/auth"; // Features
import { processPayment } from "../features/payment";
import { getUser } from "../entities/user"; // Entities
import { formatCurrency } from "../shared/utils"; // Shared
import { Header } from "../widgets/Header"; // Widgets
π‘ Tip:
fsd/ordered-imports
ensures a clean and structured import order based on FSD layers.
π€ Contributing
We welcome contributions to improve eslint-plugin-fsd-lint
!
If you have an idea for a new rule or an improvement, feel free to submit a Pull Request.
Check out our contribution guide.
π License
This project is licensed under the MIT License. See the LICENSE file for details.