underscore-internal
Disallow @internal APIs that are not underscore-prefixed.
Targeted pattern scopeโ
This rule checks identifier names for declarations/signatures such as:
- class/function/type/interface/enum declarations,
- variable declarators,
- class methods/properties,
- interface method/property signatures,
- enum members.
It reports names that do not start with _ when @internal is present in a
leading comment for the node (or its export declaration wrapper).
What this rule reportsโ
This rule reports declarations tagged with @internal when their names do not begin with _.
The convention makes internal-only APIs visually obvious and helps prevent accidental public use.
Why this rule existsโ
It enforces a consistent signal that internal-only APIs are not part of the public contract.
โ Incorrectโ
/** @internal */
export function parseSecret(): void {}
export interface Thing {
/** @internal */
compute(): number;
}
โ Correctโ
/** @internal */
export function _parseSecret(): void {}
export interface Thing {
/** @internal */
_compute(): number;
}
Behavior and migration notesโ
This rule reports only and does not provide an autofix.
Migration is typically renaming internal declarations to use an underscore prefix.
Optionsโ
This rule has no options.
Additional examplesโ
/** @internal */
export const token = "x";
// โ reported
/** @internal */
export const _token = "x";
// โ
valid
ESLint flat config exampleโ
import etcMisc from "eslint-plugin-etc-misc";
export default [
{
plugins: { "etc-misc": etcMisc },
rules: {
"etc-misc/underscore-internal": "error",
},
},
];
When not to use itโ
Disable this rule if your project uses a different naming convention for internal APIs.
Package documentationโ
Rule catalog ID: R076
Further readingโ
Adoption resourcesโ
- Start at warning level in CI, then move to error after cleanup.
- Use focused codemods/autofix batches per package or directory.