Skip to content

@noctcore/eslint-plugin-monorepo

Workspace package boundaries: barrel-only imports and exports-map-aware subpaths.

In a workspace, reaching into @acme/ui/src/button/internal works on your machine and couples two packages to a file layout neither of them published. These rules keep cross-package imports on the surface each package actually exposes.

It will yell at you about deep imports across workspace packages. no-deep-package-imports is the strict policy (barrel only), no-unexported-subpath-import the looser one (anything the target’s exports map publishes); pick one. Both ship off in the preset, because neither can do anything without your scopes, so enabling recommended alone checks nothing. It is a bad fit for a single-package repo, and no-unexported-subpath-import reads each target’s package.json from disk, so it needs a real checkout.

Install
npm install --save-dev @noctcore/eslint-plugin-monorepo @typescript-eslint/parser
# or: bun add -D / pnpm add -D @noctcore/eslint-plugin-monorepo @typescript-eslint/parser
eslint.config.js
// eslint.config.js
import tsParser from '@typescript-eslint/parser';
import monorepo from '@noctcore/eslint-plugin-monorepo';
export default [
{
...monorepo.configs.recommended,
files: ['**/*.{ts,tsx}'],
languageOptions: { parser: tsParser },
},
];
// Rules outside the preset are enabled one by one, e.g.
// { rules: { 'noctcore-monorepo/no-deep-package-imports': ['error', { /* see the rule's Options */ }] } }

The recommended preset turns none of its 2 rules on: each needs options only your project can give, so the preset alone checks nothing. Enable them with your options, as each rule's page shows.

Each rule links to its page, with the options it takes and Incorrect and Correct examples. A good first read is no-unexported-subpath-import.

RuleWhat it reportsPresetFixTypes
no-deep-package-importsWorkspace packages in the configured scopes must be consumed through their package barrel only — never via a deep subpath into package internals.off
no-unexported-subpath-importImporting a @scope/pkg/<subpath> that the target workspace package's exports map does not expose. Reads the target package.json from disk.off

Preset: severity in configs.recommended; off means the preset registers the rule switched off, not listed means it leaves the rule out; both are opt-in, so you turn the rule on yourself. Fix: whether the rule ships an autofix or an editor suggestion. Types: whether the rule needs a type-checked program (parserOptions.projectService).