JavaScript kod sa obojenom sintaksom na tamnom ekranu

Kako nadograditi Node.js projekat na novu LTS verziju

13/11/2026

Kako nadograditi Node.js u postojećem projektu tako da produkcija ništa ne primeti? Ne jednom komandom, već redosledom koji vam sve vreme ostavlja put nazad. Instalaciju nove verzije na računar opisali smo u tekstu kako ažurirati Node.js, a ovde je reč o projektu: kodu, zavisnostima, CI-ju i produkciji. U novembru 2026. cilj za većinu projekata je Node.js 26, koji je 28. oktobra postao LTS.

Pet koraka nadogradnje Node.js projekta na novu LTS verziju
Redosled koji nadogradnju čini povratnom.
  1. Na verziji koju već koristite pokrenite testove sa --throw-deprecation i uklonite svako upozorenje o zastarelom API-ju.
  2. Pročitajte beleške o izdanju (release notes) za svaku glavnu verziju između stare i nove, uključujući neparne.
  3. Dodajte novu verziju u CI matricu i popravite sve što padne, uključujući nativne module.
  4. U jednom commitu promenite verziju svuda gde je zapisana: .nvmrc, package.json, Dockerfile i podešavanja platforme.
  5. Taj commit pustite u produkciju sam. Ako nešto krene po zlu, povratak je git revert i novi deploy.

Na koju LTS verziju preseliti projekat

Za produkciju tim koji razvija Node.js preporučuje samo verzije u fazi Active LTS ili Maintenance LTS (raspored izdanja na nodejs.org). Projekat se zato seli na jednu od dve linije: Node.js 26 (Lithium) je Active LTS od 28. oktobra, sa podrškom do 30. aprila 2029, a Node.js 24 (Krypton) je Maintenance LTS, sa podrškom do 30. aprila 2028. Linija 20 je bez podrške od kraja aprila 2026. Sve linije sa poslednjim izdanjima su u tabeli u tekstu kako ažurirati Node.js.

Projekat na Node.js 22 ima još oko pet i po meseci podrške, do 30. aprila 2027. Prelazak na 26 znači dve beleške o izdanju više nego prelazak na 24, ali i godinu dana podrške više. Zato je 26 bolji cilj, osim kada ga platforma još ne nudi. Na AWS Lambdi je nodejs26.x 12. novembra u javnom preview-u, koji AWS ne preporučuje za produkciju, pa tamo za sada pređite na nodejs24.x. Vercel već nudi 26.x kao podrazumevanu verziju.

Od Node.js 27, čija je linija sada u alpha fazi, glavna verzija izlazi jednom godišnje i svaka postaje LTS, pa pravilo da LTS dobijaju samo parne verzije prestaje da važi.

Prvo počistite upozorenja na verziji koju već imate

API u Node.js-u retko nestane bez najave. Prvo se označi kao zastareo samo u dokumentaciji, zatim počne da ispisuje upozorenje pri pokretanju, a tek onda se uklanja. Primer je DEP0176, koji se odnosi na konstante fs.F_OK, fs.R_OK, fs.W_OK i fs.X_OK. U dokumentaciji su zastarele od verzije 20.8.0, Node.js 24 za njih ispisuje upozorenje, a u verziji 25.0.0 su uklonjene.

Ovaj slučaj je nezgodan jer ništa ne puca. Na Node.js 26 fs.R_OK je undefined, a fs.accessSync() bez režima podrazumeva F_OK. Poziv fs.accessSync(putanja, fs.R_OK) zato tiho proverava samo da li fajl postoji, a ne i da li može da se čita.

Upozorenja pretvorite u greške dok ste još na staroj verziji. Na Linuxu i macOS-u:

NODE_OPTIONS=--throw-deprecation npm test

U PowerShell-u na Windowsu (promenljiva važi do zatvaranja prozora):

$env:NODE_OPTIONS="--throw-deprecation"; npm test

Ako kod koristi zastareli API, test pada sa porukom poput DeprecationWarning: fs.R_OK is deprecated, use fs.constants.R_OK instead i izlaznim kodom 1 (provereno na Node.js 24.20.0 uz node --test). Kada upozorenje dolazi iz zavisnosti, --trace-deprecation ispisuje stek poziva, pa se iz putanje u node_modules vidi koji paket treba ažurirati. Uradite to pre promene Node.js-a, kao zasebnu izmenu.

Ako krećete sa Node.js 22, isti test ponovite i na 24. Na verziji 22 fs.R_OK još ne ispisuje upozorenje, jer je tamo zastareo samo u dokumentaciji, pa --throw-deprecation nema šta da uhvati.

Za deo zastarelih API-ja postoje zvanični codemod-ovi, alati koji sami menjaju kod. Za DEP0176 spisak zastarelih API-ja navodi:

npx codemod@latest @nodejs/fs-access-mode-constants

Pokrenite ga na posebnoj grani i pre commita pregledajte izmene sa git diff.

Pročitajte sve verzije između, i neparne

Kada prelazite sa LTS na LTS, neparnu verziju preskačete, ali ne i njene promene. Sve što je ukinuto u Node.js 25 stiže vam zajedno sa Node.js 26. Za prelazak sa 24 na 26 zato pročitajte beleške o izdanju 25.0.0 i 26.0.0, pre svega stavke označene sa SEMVER-MAJOR. Zvanični vodič za prelazak sa 24 na 26 na nodejs.org 12. novembra još ne postoji.

Tri promene iz tih izdanja mogu da pokvare build ili rad aplikacije čak i kada kod ne koristi nijedan uklonjeni API:

  • Corepack se od verzije 25 ne isporučuje uz Node.js. Ako Dockerfile ili CI pokreće corepack enable za Yarn ili pnpm, komanda ne postoji dok Corepack ne instalirate kao zaseban npm paket. Komande su u tekstu kako ažurirati Node.js.
  • Zvanični Linux binarni fajlovi od verzije 25 linkovani su sa bibliotekom libatomic, koju neke distribucije ne instaliraju podrazumevano. Bez nje se node ne pokreće i javlja error while loading shared libraries: libatomic.so.1. To pogađa i Node.js instaliran preko nvm-a, koji koristi zvanične arhive. Zvanični Docker image-i je već sadrže.
  • fetch u Node.js 26 koristi Undici 8, koji preko HTTPS-a prelazi na HTTP/2 kad god ga server podržava. U HTTP/2 odgovorima response.statusText je prazan, pa kod i testovi treba da proveravaju response.status.

Na Debianu i Ubuntu-u biblioteka koja nedostaje instalira se jednom komandom, posle koje node -v ponovo ispisuje verziju:

sudo apt install libatomic1

Pored grupe fs.F_OK, uklonjeni su response.writeHeader() na objektu http.ServerResponse (zamena je response.writeHead()) i interni moduli _stream_readable, _stream_writable i srodni.

Ako krećete sa Node.js 22, prvo pročitajte zvanični vodič za prelazak sa 22 na 24, sa spiskom codemod-ova. Iz njega izdvajamo OpenSSL 3.5 u Node.js 24: RSA, DSA i DH ključevi kraći od 2048 bita i ECC ključevi kraći od 224 bita se odbijaju, pa stari ključevi u integracijama mogu da prestanu da rade. Nove mogućnosti verzija 22 i 24 opisali smo u tekstu Node.js u 2026.

Nova verzija prvo ide u CI

Pre bilo kakve promene lokalno ili u produkciji pustite testove paralelno na staroj i novoj verziji. Primer za GitHub Actions (.github/workflows/test.yml, verzije akcija aktuelne u novembru 2026.):

name: test
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        node: [24, 26]
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-node@v7
        with:
          node-version: ${{ matrix.node }}
      - run: npm ci
      - run: npm test

GitHub prikazuje dva pokretanja, test (24) i test (26). Zbog fail-fast: false pad na jednoj verziji ne prekida drugu, pa vidite oba rezultata. Ako krećete sa 22, stavite [22, 24, 26]: verzija na kojoj testovi prvi put padnu pokazuje čije beleške o izdanju treba čitati.

Nativni moduli

Paketi sa kompajliranim C ili C++ kodom vezani su za ABI glavne verzije Node.js-a za koju su kompajlirani. Taj ABI označava broj NODE_MODULE_VERSION: za Node.js 22 to je 127, za 24 je 137, a za 26 je 147. Broj aktivne verzije ispisuje sledeća komanda (na Node.js 24 izlaz je 137):

node -p "process.versions.modules"

Modul kompajliran za 24 ne učitava se na 26, već baca grešku koja počinje ovako:

The module '.../paket.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 137. This version of Node.js requires
NODE_MODULE_VERSION 147.

Da li projekat uopšte ima nativne module, vidi se po fajlovima sa ekstenzijom .node. Na Linuxu, macOS-u ili u Git Bash-u na Windowsu:

find node_modules -name "*.node"

U PowerShell-u:

Get-ChildItem node_modules -Recurse -Filter *.node | Select-Object FullName

Prazan izlaz znači da kompajliranih modula nema. Ako ih ima, posle promene verzije pokrenite sledeću komandu, koja na kraju ispisuje rebuilt dependencies successfully:

npm rebuild

Izuzetak su moduli pisani za Node-API: prema dokumentaciji, rade i na kasnijim glavnim verzijama bez ponovnog kompajliranja. Ako u CI-ju sami keširate node_modules, dodajte verziju Node.js-a u ključ keša. Inače CI na Node.js 26 dobija module kompajlirane za 24 i pada sa gornjom greškom.

Verziju menjajte u jednom commitu

Kada CI prolazi na obe verzije, promenite verziju svuda odjednom. Na tri mesta stvari ne rade onako kako izgleda.

U .nvmrc upišite broj, ne lts/*

Fajl .nvmrc u korenu projekta sadrži jedan red:

26

Taj fajl čitaju nvm, fnm i actions/setup-node (preko opcije node-version-file). Oznaka lts/* deluje praktično, ali uvek vodi na najnoviju LTS verziju. Od 28. oktobra to je 26, pa je svaki projekat sa lts/* prešao na novu glavnu verziju pri sledećem nvm install ili CI pokretanju, bez ičije odluke. Isto važi za Docker oznaku node:lts, koja od tada vodi na 26. Oznaka node:latest je na 26 još od maja. Koja je verzija zaista aktivna kad ih imate više, pokazuje tekst kako proveriti da li je Node.js instaliran.

Šta engines i devEngines zaista blokiraju

Polje engines u package.json mnogi doživljavaju kao zabranu, a npm ga podrazumevano tretira kao savet. Ponašanje smo proverili sa npm 11.19.0 i Node.js 24.20.0 na Windowsu 11, uz zahtev za verziju 26:

Podešavanjenpm install i npm cinpm run
samo enginesupozorenje EBADENGINE, instalacija prolaziradi
engines i engine-strict=true u .npmrcgreška EBADENGINEradi
devEngines.runtime sa "onFail": "error"greška EBADDEVENGINESgreška EBADDEVENGINES

Ako želite da projekat odbije pogrešnu verziju i lokalno, koristite oba polja. engines čitaju i neke platforme za deploy, a devEngines npm proverava pre install, ci i run:

{
  "engines": {
    "node": "^26"
  },
  "devEngines": {
    "runtime": {
      "name": "node",
      "version": "^26",
      "onFail": "error"
    }
  }
}

npm podržava devEngines od verzije 10.9.0, a aktuelna izdanja Node.js 22, 24 i 26 dolaze sa novijim npm-om. Na Vercelu engines.node određuje i verziju za deploy i ima prednost nad podešavanjem projekta. Otvoren opseg kao >=22.0.0 tamo danas daje najnoviji 26.x, pa ga zamenite opsegom vezanim za jednu glavnu verziju, kao što je ^26 iz primera.

U Dockeru promenite samo Node.js

Oznake bez imena distribucije menjaju i operativni sistem. node:24-slim je zasnovan na Debianu 12 (bookworm), a node:26-slim na Debianu 13 (trixie). Ko promeni samo broj, dobija i noviju distribuciju sa drugim verzijama sistemskih biblioteka. Da bi se menjala jedna stvar, navedite distribuciju:

FROM node:26-bookworm-slim

Prelazak na trixie uradite kasnije, kao posebnu izmenu. Druga razlika je Yarn: od Node.js 26 zvanični image-i više ne sadrže Yarn 1 (Classic). Dockerfile koji na node:24 image-u pokreće yarn install na 26 pada dok Yarn ne dodate sami, pre te komande:

RUN npm install -g yarn@1

Deploy i povratak

Ako se u istom deployu sa novom verzijom nađu i ažurirani paketi, posle greške ne znate šta ju je izazvalo, a revert vraća i jedno i drugo. Zato npm update uradite pre ili posle, nikad u istom commitu. Isto važi za selidbu na drugi hosting: ako ste se posle našeg pregleda deployment servisa za Node.js aplikacije odlučili za promenu, uradite je kao poseban korak.

Za povratak, revert pravi novi commit koji poništava promenu verzije:

git revert <hash-commita>

Posle novog deploya produkcija ponovo radi na 24. Verziju promenjenu u podešavanjima platforme revert ne vraća, pa nju vratite ručno. Lokalno, sa nvm-om na Linuxu ili macOS-u, vratite verziju i ponovo kompajlirajte nativne module, koji su u međuvremenu kompajlirani za ABI 147. Prva komanda ispisuje Now using node v24...:

nvm use 24
npm rebuild

Staru verziju ostavite u CI matrici dok ne odlučite da se na nju više nećete vraćati. Dok je tu, CI javlja kada novi kod počne da koristi nešto čega na 24 nema, na primer Temporal, koji je u Node.js 26 uključen podrazumevano. Tako povratak ostaje jedan revert, a ne popravka koda pod pritiskom.