@mandujs/oxlint-plugin-fsd
v0.1.2
Published
Feature-Sliced Design rules for Oxlint JS plugins
Downloads
406
Readme
@mandujs/oxlint-plugin-fsd
Oxlint JS plugin project for Feature-Sliced Design rules.
This package currently ships these rules:
fsd/no-cross-slice-dependencyfsd/forbidden-importsfsd/no-global-store-importsfsd/ordered-importsfsd/no-public-api-sidestepfsd/no-relative-importsfsd/no-ui-in-business-logicfsd/backend-boundaries
This project now mirrors the original eslint-plugin-fsd-lint rule set with
an Oxlint-first implementation.
Quality gates in this package:
pnpm typecheckpnpm lintpnpm buildpnpm testpnpm test:smokepnpm bench
Install
pnpm add -D @mandujs/oxlint-plugin-fsdOxlint usage
{
"jsPlugins": [
{
"name": "fsd",
"specifier": "@mandujs/oxlint-plugin-fsd"
}
],
"rules": {
"fsd/no-relative-imports": "error"
}
}Rule behavior
fsd/no-relative-imports blocks relative imports that cross slice boundaries.
fsd/forbidden-imports enforces FSD layer direction for absolute imports.
fsd/no-public-api-sidestep blocks deep imports into internal files and forces
slice-root or segment-root public APIs.
fsd/no-cross-slice-dependency blocks imports from one slice to another inside
the same layer.
fsd/no-global-store-imports blocks direct imports of global stores such as
app/store, Redux stores, or Zustand roots.
fsd/ordered-imports keeps FSD imports grouped by layer order and supports
autofix.
fsd/no-ui-in-business-logic blocks ui imports from business-logic segments
such as model, api, and lib.
fsd/backend-boundaries enforces nested backend module boundaries such as
src/modules/<module>/{api,application,domain,infra}, src/core, and
src/shared. It also blocks cross-module deep imports unless the target is a
configured public API such as application/index.ts, infra/index.ts, or a
module root file.
Allowed by default:
- Relative imports within the same slice
- Relative imports inside
app - Relative imports inside
shared
Blocked by default:
features/foo/...importing../bar/...entities/user/...importing../workspace/...features/foo/...importing@/widgets/barentities/user/...importing@/features/workspace@/entities/user/model/internal@/features/auth/model/session/private@/features/projects/modelfrom@/features/tasks/...../../projects/model/statefrom anotherfeatures/tasks/...file@/app/store@/shared/store../ui/Buttonfrommodelorlib@/entities/user/ui/Cardfrommodelorapisharedimports placed abovefeaturesmodules/foo/application/commands/internalfrom another backend modulemodules/foo/infra/prisma/repositoryfrom backendapplication
Options
{
"rules": {
"fsd/no-relative-imports": [
"error",
{
"allowSameSlice": true,
"allowTypeImports": false,
"testFilesPatterns": ["**/*.test.*", "**/*.spec.*", "**/*.stories.*"]
}
]
}
}Backend usage:
{
"rules": {
"fsd/backend-boundaries": [
"error",
{
"alias": {
"value": "@",
"withSlash": true
},
"sourceRootPattern": "/src/",
"modulesDir": "modules"
}
]
}
}Default backend layer policy:
module-apican importmodule-application,core, andshared.module-applicationcan importmodule-domain,core, andshared.module-domaincan importmodule-domainandshared.module-infracan importmodule-application,module-domain,core, andshared.corecan importcoreandshared.sharedcan importsharedonly.
Default backend public API patterns for cross-module imports:
applicationandapplication/index.tsinfraandinfra/index.ts- module root
*.module.ts - module root
*.service.ts
Useful backend options:
enforceCrossModulePublicApi: falsedisables cross-module public API checks while keeping layer direction checks.allowSameModuleSameLayer: falsereports same-module same-layer imports instead of allowing local layer internals.allowTypeImports: trueskips type-only imports.publicApiPatternsreplaces the default public API regex list.
Presets
configs.baseconfigs.recommendedconfigs.strictconfigs.backend
Local development
pnpm install
pnpm typecheck
pnpm lint
pnpm build
pnpm test
pnpm test:smokepnpm test runs the Vitest parity suite.
pnpm test:smoke runs the built plugin against the fixture manifest with real
Oxlint subprocesses.
pnpm bench measures fixture execution time across the full manifest.
Implementation note:
createOncerules must readcontext.optionsinsidebefore()or later hooks. Oxlint initializes the rule first and attaches per-file options after that. This package treats option-sensitive logic as per-file setup.
Semantic coverage
The fixture suite covers:
- layer direction checks including direct higher-layer root files
- same-layer cross-slice imports
- valid and invalid
@xpublic APIs @x/indexpublic APIs- referenced
tsconfigpath aliases - shared
liband shareduipublic API behavior - ordered-import autofix and comment preservation
- backend nested layer direction and cross-module public API checks
CI
GitHub Actions runs typecheck, lint, build, test, and test:smoke on
every push and pull request.
