Skip to content

no-cloned-component-folders

A component folder name may exist under only one feature.

Runs under: @noctcore/harness lint-meta, not ESLint · Factory: createNoClonedComponentFoldersRule from @noctcore/lint-meta-rules · Category: source-text · Fails CI by default: yes

Same-named component folders across features are how sibling drift starts: a component cloned into a second feature diverges silently until the two are subtly incompatible. A genuinely shared surface belongs in a shared destination (e.g. components/ui); a genuinely different one deserves a name that says so.

A <feature>/<Name>/<barrelFile> path marks a component folder. Grouping by <Name> across features (excluding excludedFeatures), any name appearing under two or more features — and not in allowedClones — is flagged. The allowlist freezes today’s clone groups and only shrinks: an allowedClones entry whose clone group no longer exists is itself flagged as stale.

  • A component folder name that exists under only one feature.
  • Folders under excludedFeatures (ui and app by default).
  • Names in allowedClones while their clone group still exists.
  • Folders without the barrelFile, and folders nested deeper than <feature>/<Name>/ under componentsRoot.
createNoClonedComponentFoldersRule(options?: NoClonedComponentFoldersOptions): IMetaRule
Option Type Default Meaning
componentsRoot string 'apps/web/src/components' Root under which <feature>/<Component>/ folders live.
barrelFile string 'index.ts' Barrel file that marks a component folder.
excludedFeatures string[] ['ui', 'app'] Feature folders whose contents are not feature components.
allowedClones string[] [] Component names allowed to be cloned (a shrinking allowlist).
sharedDest string 'components/ui' Where a shared surface should be hoisted (used in the message).
ciCritical boolean true Whether a violation fails CI.

If your components are not organized as <feature>/<Component>/ folders under one root, or you intentionally maintain per-feature variants, retune or skip the rule.