A package.json szkriptjeit nem csak az npm run tudja elindítani. A Node.js 22 óta maga a Node is képes rá, csomagkezelő nélkül:
node --run test
node --run build -- --watch
A rövidebb út érezhetően gyorsabb lehet, különösen akkor, ha sok apró szkript indul egymás után. A két parancs azonban nem csereszabatos. A node --run szándékosan kevesebbet csinál, és a kihagyott lépésekre nem figyelmeztet.

Mit csinál a node --run?
A Node.js CLI dokumentációja szerint a kapcsoló megkeresi a package.json scripts mezőjében a megadott parancsot, majd lefuttatja. Az argumentumokat a -- után lehet továbbadni a szkriptnek.
A funkció a Node.js 22.0.0-ban jelent meg 2024. április 24-én. Nem indítja el az npm parancssori felületét, nem olvassa be annak teljes konfigurációját, és nem építi fel az npm által megszokott környezetet. A Node közvetlenül keresi meg és futtatja a szkriptet.
A különbség főleg rövid szkripteknél látszik
Az indítási többletet egy olyan szkripttel mértem meg, amely azonnal kilép: node -e "process.exit(0)". Node.js 22.22.3 és npm 10.9.8 alatt húsz egymást követő futtatásból ezt kaptam:
npm run hello × 20: ≈ 3,02 s
node --run hello × 20: ≈ 0,76 s
Ezen a gépen tehát nagyjából négyszeres volt a különbség. Ez nem általános benchmark, hanem az indítási költség szemléltetése. Egy többperces buildnél a megtakarított néhány tizedmásodperc eltűnik a zajban. Monorepóban, sok workspace-en végigfutó CI-lépéseknél vagy gyakran újrainduló fejlesztői szkripteknél viszont összeadódhat.
A pre- és post-szkriptek kimaradnak
Az npm életciklusához hozzátartozik, hogy egy test szkript körül automatikusan lefuttatja a pretest és posttest parancsokat is, ha léteznek. Ezt az npm szkriptekről szóló dokumentáció is rögzíti.
{
"scripts": {
"pretest": "npm run lint",
"test": "node --test",
"posttest": "npm run report"
}
}
Az npm run test ebben a példában mindhárom lépést sorban végrehajtja. A node --run test csak a középsőt indítja el. Nem jelez hibát, és nem ír ki figyelmeztetést, hiszen ez dokumentált, szándékos korlátozás.
A különbség könnyen elbújik egy CI-módosításban. Ha a lintelés vagy a riportkészítés életciklus-hookban él, a parancs egyszerű cseréjével az ellenőrzés csendben kiesik a pipeline-ból.
Az npm környezeti változói sem jelennek meg
Az npm futás közben több npm_* kezdetű környezeti változót állít be. Ilyen például az npm_package_version és az npm_lifecycle_event. Build- és kiadási szkriptek gyakran ezekből olvassák ki a verziót vagy az aktuális lifecycle eseményt.
npm run showvars:
npm_package_version=1.2.3
npm_lifecycle_event=showvars
node --run showvars:
npm_package_version=undefined
npm_lifecycle_event=undefined
A hiányzó változó önmagában nem feltétlenül állítja le a folyamatot. Egy gondatlan, Docker image-et címkéző szkript akár az undefined szót is beépítheti a címkébe. Ezért a migráció előtt érdemes rákeresni a szkriptjeinkben a process.env.npm_ használatára, nem csak arra hagyatkozni, hogy a parancs sikeresen lefut.
A Node saját változókat ad
A node --run két dokumentált környezeti változót állít be: a NODE_RUN_SCRIPT_NAME a futtatott szkript nevét, a NODE_RUN_PACKAGE_JSON_PATH pedig a feldolgozott package.json elérési útját tartalmazza. Ezek a Node.js 22.3.0 óta érhetők el.
Ugyanettől a verziótól a parancs felfelé halad a könyvtárfában, amíg talál egy package.json-t. Az érintett szülőkönyvtárak node_modules/.bin mappáit hozzáadja a PATH-hoz, ezért egy mélyebben fekvő workspace szkriptje a gyökérben telepített binárisokat is elérheti.
Mikor érdemes váltani?
Jó jelölt egy önálló build-, teszt- vagy segédszkript, amelyet gyakran indítunk, és nem támaszkodik az npm környezetére. A csere előtt három dolgot néznék végig:
- tartozik-e a szkripthez
prevagyposthook; - olvas-e
npm_*környezeti változót; - elérhető-e minden szükséges bináris a
node --runáltal felépítettPATH-on.
Ha mindhárom rendben van, a node --run egyszerű és gyors eszköz. Örökölt, sok lifecycle hookból felépülő szkriptrendszernél viszont nem gyorsabb npm-helyettesítő, hanem eltérő viselkedésű futtató. A valódi kérdés ezért nem az, mennyivel hamarabb indul el, hanem az, hogy ugyanazt a munkát indítja-e el.