A linter for Angular applications that checks relationships between files.
ESLint operates on single files. It cannot verify that a component's stub matches its real implementation, or that an interface file exists for a component that needs one.
ng-nudge fills this gap. It understands that Angular components are collections of related files, and it verifies that those files work together correctly.
Add to your project's package.json:
{
"devDependencies": {
"ng-nudge": "git+ssh://git@github.com:OverTheTopMarketing/ng-nudge.git"
}
}Then run:
npm installRun from your Angular project's root directory:
npx ng-nudge [OPTIONS]Or add to your package.json scripts:
{
"scripts": {
"ng-nudge": "ng-nudge"
}
}| Flag | Description |
|---|---|
--warnings=all |
Show all warnings (default) |
--warnings=none |
Suppress warnings |
--warnings=error |
Treat warnings as errors |
-q, --quiet |
Only report failures |
-s, --silent |
No output, only exit code |
-d, --update-debt |
Snapshot current violations into debt.tsv |
-h, --help |
Show help message |
0— All checks passed1— Violations detected, or stale debt entries exist
ng-nudge expects your project to have:
- A
tsconfig.jsonin the project root - A
src/directory containing Angular components
It uses a policy/rule architecture:
Policies decide when rules apply. For example, HasStub applies only to components that have a stub file.
Rules perform the actual checks. For example, StubMatchesComponent verifies that a stub has all the inputs and outputs defined in the real component.
| Policy | Description |
|---|---|
HasInterface |
Components with interface files must have stubs |
HasStub |
Stubs must have interfaces and match their components |
HasStyles |
Components with styles should prefer .css over .scss |
HasDebt |
Violations recorded in debt.tsv must be resolved or documented |
| Rule | Severity | Description |
|---|---|---|
StubExists |
Error | Stub file must exist |
InterfaceExists |
Error | Interface file must exist |
StubMatchesComponent |
Error | Stub must have all component inputs/outputs |
PreferCssOverScss |
Warning | Use .css instead of .scss |
HasDebtRule |
Error | Each debt entry is a tracked violation |
Create a new file in rule/ following the pattern:
import { Violation } from '../violation.mjs';
export class MyRule {
#component;
constructor(component) {
this.#component = component;
}
get violations() {
if (somethingWrong) {
return [new Violation(this.#component, 'description of problem')];
}
return [];
}
}Then add it to a policy in policy/.
ng-nudge can track known violations so you can enforce stricter rules for new code while tolerating existing debt at a lower severity.
Run npx ng-nudge --update-debt to snapshot current violations into .config/ng-nudge/debt.tsv. On subsequent runs, ng-nudge skips violations present in the debt file and only reports new ones.
When a violation is fixed, ng-nudge logs ★ Debt paid off and exits with code 1, prompting you to re-run --update-debt to remove the stale entry.
The debt file is a TSV with three columns: Rule, Artifact, and Comment. The first two are populated automatically. The Comment column is for you — add a short note explaining why the violation is being tolerated (e.g., legacy component, refactor planned).
The withComment rule option controls how commented entries affect severity. Set it in rc.json:
{
"rules": {
"has-debt": {
"withComment": "warning"
}
}
}This caps commented debt entries at warning severity, so uncommented entries remain errors while documented ones become warnings. Accepted values:
true— cap at warning"none"— suppress commented entries entirely"warning"or"error"— set the ceiling explicitly{ "maxSeverity": "warning", "matching": "regex" }— apply the cap only to comments matching the pattern