Elm vs. React. Stillheten eller stormen?

Elm har ikke hatt en major release siden 2019. React oppdateres stadig, og verden rundt JavaScript beveger seg i høyt tempo. Nye rammeverk, meta-rammeverk, bundlere og eksperimentelle features dukker opp i rask rekkefølge. Hva skjer når man sammenligner dette «raske» og stadig skiftende økosystemet med det stille, stabile og nærmest urokkelige Elm-universet? Hvordan påvirker det måten vi jobber på, og hva gjør det med utviklerens hverdag og mentale kapasitet?

Rammeverkstretthet og pakkeinferno

Det er en kjent følelse for mange frontend-utviklere: hver uke et nytt rammeverk, ny build-pipeline, nye pakker og nye «best practices». Du åpner prosjektet ditt og blir møtt med en advarsel fra npm audit eller en peer dependency-konflikt du ikke visste fantes. Det er et vedvarende tempo som krever vedlikehold – ikke bare av produktet, men av selve utviklingsverktøyene. Det føles ofte som om du ikke bare bygger funksjonalitet, men hele tiden må reparere grunnmuren mens du bygger huset.

React er fortsatt bransjestandarden, men har gått fra et bibliotek til en hel plattform – med nye API-er (Hooks, Server Components), ny build-støtte (Next, Vite), og stadig endring i hvordan vi forventes å tenke om state, sideeffekter og reaktivitet. Med fleksibilitet følger valgfrihet, men også usikkerhet – for hvilken strategi er egentlig riktig akkurat nå? Og hva gjør det med langsiktig vedlikeholdbarhet?

Elm: Et språk i ro – på godt og vondt

Elm 0.19 ble sluppet i 2019. Siden det har det vært bemerkelsesverdig stille. Ingen nye features. Ingen breaking changes. Ingen diskusjoner om hvilken router, hook-løsning eller formhåndtering du burde bruke – fordi det finnes én løsning på det meste, og den funker. Det er som å komme til en landsby der alt er på plass, tempoet er lavt og behovet for raske grep rett og slett ikke finnes.

For mange føles dette som en svakhet. For andre, som et pusterom. Med Elm slipper du å bruke tiden på å vedlikeholde toolchain. Du bruker den på å bygge produkt. Det er en annen utviklingsfilosofi, og for mange utviklere kjennes det nesten terapeutisk. Det er som å få tilbake kontrollen over verktøyene dine.

Hva Elm prioriterer – og hva det koster

Lav kognitiv belastning som designmål

I en tidligere artikkel skrev jeg om hvordan god kode også handler om psykologi – og spesielt hvordan vi kan redusere kognitiv belastning i utviklingsarbeidet. Elm er et prakteksempel på et språk og økosystem som bevisst tar tak i dette.

Elm sin rene funksjonelle natur, strenge typesystem, forutsigbare struktur (The Elm Architecture) og fravær av valgfrihet rundt verktøy gjør at du som utvikler slipper å holde mange mentale modeller i hodet samtidig. Du trenger ikke konstant vurdere hvilken state management-løsning du skal bruke, hvilken router som passer best, eller hvordan du skal kombinere hooks på rett måte. Alt dette er allerede bestemt – og det gir deg kapasitet til å fokusere på det viktigste: brukerens behov og produktets logikk.

Denne reduksjonen i kognitiv belastning gjør ikke bare utviklingen mer behagelig – det gir også bedre kode, fordi vi mennesker tenker og jobber bedre når vi ikke er kognitivt overbelastet.

Ekte funksjonell programmering

Elm er også et språk som tar funksjonell programmering på alvor – ikke bare som et sett med ideer, men som en grunnmur. Her finnes ingen mutable data, ingen null, ingen this, og ingen unntak. Alt er rene funksjoner, og det er ikke valgfritt.

Det gir store fordeler:

  • Koden blir mer forutsigbar og lettere å teste
  • Du kan stole på at data ikke endrer seg bak ryggen din
  • Hele applikasjonen blir enklere å forstå som en serie av transformasjoner
  • Kompilatoren fanger en utrolig mengde feil – før du i det hele tatt har kjørt appen
  • Arkitekturen gjør det lettere å isolere ansvar og jobbe strukturert, uansett teamets størrelse

Dette er «ekte» funksjonell programmering, og det er nettopp denne radikaliteten som gjør Elm så robust – og annerledes enn mange JS-baserte rammeverk som låner litt av det funksjonelle tankegodset, men ikke følger det hele veien. Elm gir deg trygghet, og den tryggheten gjør at du tør å bygge mer med færre tester og mindre kompleksitet.

Fordeler og ulemper

Flere har påpekt at stillstanden i utviklingen av Elm, både språket og økosystemet, kan oppleves frustrerende. Men som denne artikkelen på Elmcraft påpeker, er dette et bevisst valg. Elm utvikles sakte, og med et sterkt fokus på å unngå breaking changes og bevare stabilitet for brukerne. Det betyr at dokumentasjon, tutorials og eksisterende prosjekter holder seg relevante i årevis – og at utviklere slipper å forholde seg til en konstant strøm av nye paradigmer eller API-endringer.

Elm tar bevisste valg for stabilitet og langsiktighet. Det betyr:

  • Ingen runtime exceptions
  • Et pakkeøkosystem med strenge kvalitetskrav og automatisk semantisk versjonering
  • En kompilator som gir ekstremt tydelige (og vennlige!) tilbakemeldinger
  • API-design som prioriterer forståelse over fleksibilitet
  • En helhetlig arkitekturmodell gjennom The Elm Architecture (TEA), som gir struktur og forutsigbarhet uten å påtvinge deg kompliserte patterns
  • Mindre behov for tredjepartsverktøy, fordi verktøyene som følger med faktisk strekker til

Men det har også en pris:

  • Lang ventetid på nye features
  • Mindre community-drevet innovasjon
  • Manglende støtte for det nyeste innen webstandardenes utvikling
  • Mindre fleksibilitet for deg som ønsker å eksperimentere med cutting-edge teknologi

Mange av disse ulempene må likevel sees i lys av hvor annerledes Elm tenker om frontend enn nesten alt annet i bransjen. Der React og resten av JS-verdenen jobber tett med DOM og JavaScript som en integrert del av applikasjonslogikken, behandler Elm disse som et rent grensesnitt – som en I/O-enhet.

Elm går så langt som å bruke begrepet «ports» (fra «Ports and Adapters»-arkitekturen) for å beskrive koblingen mot JavaScript, og setter en tydelig grense mellom funksjonell forretningslogikk og sideeffekter. Dette minner om hvordan Uncle Bob beskriver weben som en detalj – en implementasjonsdetalj du bør isolere, ikke blande med kjernelogikken.

Med denne arkitekturen kan Elm-kode skrevet i 2019 fortsatt samhandle med bleeding-edge JavaScript, fordi det nettopp er en I/O-enhet. Frontendens verden kan endre seg, men Elm-koden forblir stabil så lenge port-grensesnittet opprettholdes. Du kan bruke moderne Web APIs, Web Components eller hvilket som helst nytt JavaScript-bibliotek gjennom ports – uten å måtte endre en linje i domenelogikken din.

I applikasjonen jeg jobber med til daglig hos Lovdata bruker vi for eksempel native <dialog>-elementer i DOM-en sammen med MutationObserver i JavaScript. Ingenting av dette fantes i 2019 – men det fungerer utmerket i Elm likevel.

Filosofisk forskjell: Tempo vs. tillit

JS-verdenen feirer fart, fleksibilitet og fellesskapsbygging. Det skjer mye bra her, men også mye støy. Et nytt paradigme eller buzzword får ofte fotfeste før det er modent, og utviklere må tilpasse seg før praksisen har satt seg. Elm velger stillhet, konsistens og stabilitet. Det gjør kanskje at du bygger litt saktere, men til gjengjeld bygger du på et grunnlag du kan stole på over lang tid.

Det handler ikke om teknologisk stagnasjon, men om tillit. Tillit til at det som finnes, fungerer. At det du skriver i dag også fungerer i morgen. Og at rammeverket ikke tvinger deg i en ny retning neste gang du oppdaterer en pakke.

I en tid der verktøykjedene raser videre med nye versjoner, ny syntaks og stadig flere avhengigheter, kan det være verdt å stoppe opp og spørre: Trenger vi egentlig alt dette, eller trenger vi mer ro og retning? Kanskje er det ikke vi som må løpe fortere, kanskje er det verktøyene som bør roe seg ned.