# ESLint

## Hva det er

ESLint er et verktøy med åpen kildekode for statisk analyse av JavaScript. Det leser kildekoden,
tester den mot et sett regler som er satt opp for prosjektet, og melder fra om hvert sted koden
bryter en av dem, og de enkleste tilfellene retter det selv når du ber om det. På kommandolinjen
heter det `eslint`, og det installeres fra npm som en utviklingsavhengighet i det prosjektet det
sjekker. Nicholas C. Zakas startet det i juni 2013, og prosjektet presenterer seg fortsatt som en
konfigurerbar linter for JavaScript.

Selve programmet blir aldri kjørt. En parser gjør hver fil om til et abstrakt syntakstre i formatet
ESTree, og hver regel er en liten modul som ber om å bli kalt ved bestemte slags noder: hver
funksjon, hver sammenligning, hver `await`. Regelen ser på det den får, og er noe galt, melder den
en beskjed og et sted i koden. Noen regler har også en retting (fix), en endring prosjektet bare
godtar når den løser problemet uten å endre hva programmet gjør, og `eslint --fix` skriver slike
rettinger inn i filene. Andre regler tilbyr forslag (suggestions) i stedet. Et forslag kan endre
oppførselen, og derfor tas forslagene i bruk ett om gangen, av et menneske, i editoren.

Nesten alt rundt den kjernen kan byttes ut. Utvidelser (plugins) er programvarepakker fra npm som
legger til regler, delbare konfigurasjoner, prosessorer eller støtte for andre språk. En annen
parser lar ESLint lese syntaks som standardparseren ikke forstår, f.eks. TypeScript. Prosessorer
henter JavaScript ut av andre filer, f.eks. kodeblokkene i et Markdown-dokument, og formaterere
endrer hvordan rapporten skrives ut. Prosjektet beskriver selv filosofien sin slik: hver regel står
for seg selv, kan slås av og kan settes til å advare eller til å feile, helt på egne premisser.

Alt dette settes opp i én JavaScript-fil i roten av prosjektet, som regel `eslint.config.js` eller
variantene `.mjs` og `.cjs`, og filen eksporterer en liste (array) med objekter. Hvert objekt sier
hvilke filer det gjelder for, og hvilke regler, globale variabler og parseropsjoner som skal gjelde
for dem, og senere objekter overstyrer tidligere. Dette oppsettet, kalt flat config, ble standard i
ESLint v9.0.0 den 5. april 2024. ESLint v10.0.0, utgitt 6. februar 2026, fjernet det eldre formatet
`.eslintrc` og filen `.eslintignore` helt.

## Hvorfor det er viktig

En linter gjør seg fortjent til plassen sin i ett bestemt øyeblikk: når den hindrer at en endring
blir slått sammen. ESLint tar den avgjørelsen gjennom avslutningskoden sin (exit code), og
avslutningskoden følger alvorlighetsgraden. Hver regel er satt til `"off"`, `"warn"` eller
`"error"`. En feil får kommandoen til å avslutte med 1. En advarsel skrives ut, og kommandoen
avslutter likevel med 0, med mindre `--max-warnings` setter et tak, og det taket er slått av som
standard. Avslutningskode 2 er satt av til en ødelagt konfigurasjon eller et internt krasj.

Den avgjørelsen et team egentlig tar med ESLint, er altså hva en advarsel skal bety. En advarsel som
aldri får et bygg til å feile, er et råd, og råd i en terminal blir rullet forbi så snart det er
førti linjer av dem. Team som vil at linteren skal holde en grense, setter enten hver regel de bryr
seg om, til `"error"`, eller kjører kvalitetsporten med `--max-warnings 0`. Uansett hvilken vei de
går, lintes en sunn gren helt ren, og én enkelt ny linje i utskriften er en nyhet som noen faktisk
leser.

Gevinsten ligger i det JavaScript slipper gjennom. Språket laster uten protester en fil som viser
til en variabel ingen har deklarert, definerer den samme nøkkelen to ganger i en objektliteral,
sammenligner en verdi med `NaN` ved hjelp av `===` eller har kode etter en `return` som aldri kan
kjøre. Hver av disse feiler først når akkurat den linjen kjøres, og det kan godt være i produksjon.
Reglene i ESLints anbefalte sett fanger alle fire før kodegjennomgangen, og da kan den som går
gjennom koden, lese for designet.

Det har en pris. En konfigurasjon samler opp meninger, og en regel som slår ut på korrekt kode,
lærer folk å slutte å lese utskriften, og det er verre enn å ikke ha regelen. En linter er dessuten
bare så god som øyeblikket den kjører i: en som bare kjører i en editor, på noen av maskinene,
sjekker noe av koden noe av tiden.

## Slik ser det ut i praksis

ESLint var én av seks lintere bak
[en kvalitetsstandard med null advarsler for seks språk](/nb/portfolio/set-a-zero-warnings-quality-bar-across-six-79/),
der den sjekket TypeScript ved siden av golangci-lint for Go, SQLFluff for SQL, Ruff for Python,
ShellCheck for skallskript og markdownlint for Markdown. Det som fikk standarden til å holde, var
spørsmålet om alvorlighetsgrad ovenfor, avgjort én gang for alle: hver linterdiagnostikk er en feil,
det finnes ikke noe «warn»-nivå å gjemme seg i, og inline-undertrykkelser er forbudt. Pre-commit- og
pre-push-hooks kjører linterne og testene, så en commit som ville ha introdusert et problem, blir
aldri laget.

Det samme repoet trengte etter hvert regler som ingen publisert pakke leverer, de som handler om
hvordan akkurat den kodebasen er ment å virke.
[Femten egne ESLint-regler holder husets mønstre på plass i TypeScript](/nb/portfolio/built-the-repository-s-guard-engine-of-268-checks-95/),
ved siden av 274 kontrollskript, 268 av dem registrert i commit-hookene. Ett av kontrollskriptene
sjekker at ingen i det stille har lagt inn en inline-undertrykkelse. Vaktene har 146 egne tester,
fordi en ødelagt vakt slipper alt gjennom uten at noen finner det ut, og siden sier prisen rett ut:
det går tregt å committe.

Dette nettstedet holder byggeskriptene sine til den samme standarden i mindre skala. Filen
`eslint.config.mjs` tar utgangspunkt i `js.configs.recommended` og legger bare til regler som koden
allerede besto da de ble målt. Kommentarene i filen dokumenterer en ny måling 15. oktober 2026 over
alle de 199 reglene som ikke er utfaset, og den slo på 21 regler til som handler om korrekthet og
ikke om smak. Hver regel er en feil. `reportUnusedDisableDirectives`, som er en advarsel som
standard, er også hevet til feil, så en disable-kommentar som har sluttet å undertrykke noe, får
kjøringen til å feile. Skriptene deklarerer globale variabler for både Node og nettleser, fordi
funksjonskroppene de gir videre til `page.evaluate`, kjører inne i en nettleser, noen få linjer unna
kode som kjører i Node.

## Hvor det går galt

Det meste av trøbbelet med ESLint er at linteren gjør nøyaktig det konfigurasjonen sier, og det er
ikke alltid det teamet tror den sier.

**Bygget er grønt, og terminalen er full av advarsler.** Advarsler lar avslutningskoden stå på 0, så
CI går gjennom mens listen vokser med noen linjer i uka, og etter en stund ligger en ekte
programvarefeil i den uten at noen har lest den. Bestem hvilke regler som betyr noe, sett dem til
`"error"`, slå av resten, og legg `--max-warnings 0` inn i kvalitetsporten, slik at advarsler ikke
lenger kan hope seg opp.

**En disable-kommentar lever lenger enn grunnen sin.** En linje ble en gang gjort taus av en god
grunn. Koden under endret seg, kommentaren ble stående, og nå skjuler den det neste problemet på den
linjen, eller ingenting i det hele tatt. Sett `linterOptions.reportUnusedDisableDirectives` til
`"error"`, så direktiver som ikke undertrykker noe, får kjøringen til å feile, og krev en
begrunnelse etter `--` på dem som blir igjen, slik at den som går gjennom koden, kan vurdere dem:

```js
// eslint-disable-next-line no-console -- printing is this CLI's output
console.log(report);
```

**En oppgradering endrer hvilke filer som sjekkes.** Etter overgangen til v10 blir stier som
`.eslintignore` pleide å hoppe over, plutselig rapportert, eller én mappe begynner å følge andre
regler. Versjon 10 tar ikke lenger hensyn til `.eslintrc.*` eller `.eslintignore`, og den leter
etter `eslint.config.*` med start i katalogen til hver fil som lintes, så en glemt konfigurasjonsfil
i en undermappe styrer nå den undermappen. Flytt ignoreringene inn i en global `ignores`-oppføring,
konverter den gamle filen med `npx @eslint/migrate-config .eslintrc.json` og gå gjennom det
kommandoen skriver, og list så opp hver `eslint.config.*` i treet og fjern dem ingen mente å
beholde.

**Nettleserkode blir meldt som udefinert.** Et Node-skript som gir funksjoner videre til en
nettleser, får `no-undef`-feil på `document` og `window`, og så slår noen av `no-undef`, som også
skjuler ekte skrivefeil. Deklarer hvert miljø koden faktisk kjører i, gjennom
`languageOptions.globals`, for de filene som kjører der.

**En egen regel slipper alt gjennom.** En regel der visitoren navngir en nodetype som aldri
forekommer, eller der betingelsen er snudd, melder rett og slett aldri noe, og stillhet ser nøyaktig
ut som etterlevelse. Test hver egen regel med ESLints `RuleTester`, med kode som må bestå og kode
som må feile, så en regel som slutter å melde fra, feiler sin egen test før den svikter kodebasen.

## Les mer

- [Core Concepts](https://eslint.org/docs/latest/use/core-concepts/) — regler, rettinger,
  utvidelser, parsere og prosessorer, slik prosjektet selv definerer dem.
- [Configuration Files](https://eslint.org/docs/latest/use/configure/configuration-files)
  — listen i flat config, filmønstre, globale ignoreringer og hvordan objektene slås sammen.
- [Configure Rules](https://eslint.org/docs/latest/use/configure/rules) — alvorlighetsgrader,
  regelopsjoner og kommentarene som slår av en regel for én linje.
- [Command Line Interface Reference](https://eslint.org/docs/latest/use/command-line-interface)
  — hvert flagg, blant dem `--max-warnings`, og hva hver avslutningskode betyr.
- [ESLint v10.0.0 released](https://eslint.org/blog/2026/02/eslint-v10.0.0-released/)
  — utgivelsesnotatene om fjerningen av eslintrc og det nye oppslaget etter konfigurasjon.
- [Custom Rules](https://eslint.org/docs/latest/extend/custom-rules) — å skrive en regel mot
  syntakstreet og bevise at den virker, med `RuleTester`.

<https://engineer.company/nb/glossary/eslint/>
