Node.js und npm: Der Einstieg in serverseitiges JavaScript

JavaScript war lange Zeit ausschließlich im Browser zu Hause. Mit Node.js änderte sich das grundlegend: Seit 2009 können Entwicklerinnen und Entwickler JavaScript auch auf dem Server, in der Kommandozeile und in Build-Tools einsetzen. Zusammen mit dem Paketmanager npm bildet Node.js das Fundament des modernen JavaScript-Ökosystems und ist aus der Webentwicklung nicht mehr wegzudenken.

Was ist Node.js?

Node.js ist eine serverseitige Laufzeitumgebung für JavaScript, die auf der V8-Engine von Google Chrome basiert. V8 kompiliert JavaScript direkt zu Maschinencode und sorgt so für hohe Ausführungsgeschwindigkeit. Node.js ergänzt V8 um eine umfangreiche Standardbibliothek für Datei-Operationen, Netzwerkkommunikation, Kryptografie und vieles mehr.

Im Gegensatz zu traditionellen Server-Plattformen wie Apache oder nginx, die für jeden eingehenden Request einen eigenen Thread starten, arbeitet Node.js mit einem einzigen Thread und einem asynchronen, nicht-blockierenden Modell. Das ermöglicht die effiziente Verarbeitung vieler gleichzeitiger Verbindungen. Die offizielle Node.js-Dokumentation beschreibt die API ausführlich.

Das Event-Loop-Konzept

Das Herzstück von Node.js ist der Event Loop. Statt auf I/O-Operationen zu warten und dabei den Thread zu blockieren, registriert Node.js einen Callback und arbeitet in der Zwischenzeit an anderen Aufgaben weiter. Sobald die I/O-Operation abgeschlossen ist, wird der Callback in die Event Queue eingereiht und vom Event Loop ausgeführt.

Dieses Modell macht Node.js besonders geeignet für:

Für CPU-intensive Aufgaben wie komplexe Berechnungen oder Bildverarbeitung ist Node.js dagegen weniger geeignet, da diese den Single Thread blockieren würden. Hier helfen Worker Threads oder externe Prozesse.

npm: Der Node Package Manager

npm ist der Standard-Paketmanager für Node.js und kommt automatisch mit jeder Node.js-Installation. Das npm-Registry ist mit über zwei Millionen Paketen das größte Software-Repository der Welt.

Projekt initialisieren

Ein neues Node.js-Projekt wird mit folgendem Befehl gestartet:

npm init
# oder ohne interaktive Fragen:
npm init -y

Dieser Befehl erstellt die Datei package.json, die als Herzstück jedes Node.js-Projekts dient.

Pakete installieren

# Als reguläre Abhängigkeit (wird in production benötigt)
npm install express

# Als Entwicklungsabhängigkeit (nur für Entwicklung/Build)
npm install --save-dev typescript eslint

# Global installieren (CLI-Tools)
npm install -g nodemon

npm-Skripte

Im Abschnitt "scripts" der package.json lassen sich beliebige Befehle definieren, die mit npm run <name> ausgeführt werden:

"scripts": {
  "start": "node dist/index.js",
  "dev": "nodemon src/index.ts",
  "build": "tsc",
  "test": "jest",
  "lint": "eslint src/**/*.ts"
}

Struktur der package.json

Die package.json enthält alle wichtigen Metadaten eines Projekts:

Tipp: Committen Sie stets die package-lock.json (oder yarn.lock / pnpm-lock.yaml) in Ihr Repository. Diese Datei sorgt dafür, dass alle Teammitglieder und CI/CD-Systeme exakt dieselben Paketversionen installieren. So vermeiden Sie das klassische „bei mir funktioniert es"-Problem durch abweichende Abhängigkeitsversionen.

npx: Pakete ohne Installation ausführen

Mit npx lassen sich npm-Pakete direkt ausführen, ohne sie global zu installieren. Das ist besonders nützlich für einmalige CLI-Befehle:

npx create-react-app mein-projekt
npx tsc --init
npx prettier --write src/

npx ist seit npm 5.2 im Lieferumfang enthalten und lädt das Paket temporär herunter, wenn es nicht bereits installiert ist.

Typische Einsatzbereiche

Node.js eignet sich für eine breite Palette von Anwendungen:

nvm: Node-Versionen verwalten

Verschiedene Projekte benötigen oft unterschiedliche Node.js-Versionen. Der Node Version Manager (nvm) löst dieses Problem elegant:

# Version installieren
nvm install 22

# Version wechseln
nvm use 20

# Standardversion setzen
nvm alias default 22

Alternativ bietet sich auf Windows nvm-windows an. Mit einer .nvmrc-Datei im Projektverzeichnis wird die gewünschte Node-Version automatisch aktiviert.

Achtung: Installieren Sie Node.js für die Entwicklung niemals direkt als root oder Administrator und vermeiden Sie globale npm-Pakete so weit wie möglich. Nutzen Sie stattdessen nvm und lokale Projektinstallationen. Globale Pakete können bei Versionskonflikten schwer zu debuggende Probleme verursachen und erschweren die Reproduzierbarkeit von Builds.

Node.js LTS-Versionen im Vergleich

Version Codename Status Wichtige Features LTS-Ende
Node.js 18 Hydrogen End of Life Fetch API (experimentell), Test-Runner April 2025
Node.js 20 Iron Maintenance LTS Stabiler Test-Runner, Permission Model April 2026
Node.js 22 Jod Active LTS Native fetch stabil, require(ESM), V8 12.4 April 2027
Node.js 24 Current V8 13.6, npm 11, verbesserte TypeScript-Unterstützung April 2028

Für Produktionsumgebungen empfiehlt sich stets die aktuelle LTS-Version (Long Term Support). Diese wird mindestens 30 Monate lang mit Sicherheits-Updates versorgt. Den genauen Release-Zeitplan veröffentlicht das Node.js-Team auf der offiziellen Release-Seite.

FAQ zu Node.js und npm

Was ist der Unterschied zwischen dependencies und devDependencies?
dependencies enthält Pakete, die zur Laufzeit benötigt werden (z. B. Express, Prisma). devDependencies enthält Pakete, die nur während der Entwicklung gebraucht werden (z. B. TypeScript, ESLint, Jest). Bei einem Produktions-Deployment mit npm install --omit=dev werden devDependencies nicht installiert.
Was ist der Unterschied zwischen npm, yarn und pnpm?
Alle drei sind Paketmanager für Node.js. npm ist der Standard, yarn brachte früher Performance-Vorteile und Workspaces-Unterstützung, pnpm spart Speicherplatz durch harte Links. Heute sind alle drei ausgereift – die Wahl hängt meist von Team-Präferenzen oder Monorepo-Anforderungen ab.
Kann ich Node.js für Frontend-Entwicklung nutzen?
Node.js selbst läuft nicht im Browser. Aber nahezu jedes moderne Frontend-Tooling – Vite, Webpack, Babel, PostCSS – setzt Node.js voraus. Node.js ist damit das unverzichtbare Fundament für die Frontend-Entwicklung, auch wenn der produzierte Code im Browser läuft.
Was bedeutet das Caret (^) in der package.json?
Das Caret (^) erlaubt automatische Updates auf kompatible Minor- und Patch-Versionen (z. B. ^4.18.0 erlaubt 4.19.0, aber nicht 5.0.0). Die Tilde (~) erlaubt nur Patch-Updates. Für maximale Reproduzierbarkeit empfiehlt es sich, exakte Versionen ohne Präfix zu verwenden und die package-lock.json zu committen.