Server Runtime

Node.js Basics

Node.js führt JavaScript außerhalb des Browsers auf dem Server aus. Sein nicht-blockierendes I/O und das riesige Ökosystem machen es zur natürlichen Wahl für APIs, Tools und Full-Stack-Apps.

beginner15 min readUpdated 15. Sept. 2026
server.js
js
// server.js
import { createServer } from "node:http";

const server = createServer((req, res) => {
  if (req.url === "/health") {
    res.writeHead(200, { "Content-Type": "application/json" });
    res.end(JSON.stringify({ status: "ok" }));
    return;
  }
  res.writeHead(404).end("Not found");
});

server.listen(3000, () => {
  console.log("http://localhost:3000");
});
Erstveröffentlichung
2009, durch Ryan Dahl
Engine
V8
Modell
Nicht-blockierend, event-gesteuert
Module
ESM und CommonJS
Pakete
npm registry
Ideal für
APIs, Tools, Echtzeit-Apps

Warum es wichtig ist

Warum Node.js wichtig ist

JavaScript auf dem Server

Nutze dieselbe Sprache auf beiden Seiten der Verbindung, was Teams, Tooling und das Teilen von Code vereinfacht.

Nicht-blockierendes I/O

Der Event Loop verarbeitet weiterhin Anfragen, während auf Dateien, Netzwerke und Datenbanken gewartet wird, sodass der Durchsatz hoch bleibt.

Ein massives Ökosystem

npm bietet Pakete für fast jede Aufgabe, und Frameworks wie Express und Fastify machen den Bau von APIs schnell und einfach.

Das Gesamtbild

Die drei Kernideen hinter Node.js

Eine JavaScript Engine, ein nicht-blockierender Event Loop und eine Standardbibliothek für Dateien, Netzwerke und Prozesse.

Die Runtime

Ausführen

V8 plus die Node APIs für Dateien, Networking, Prozesse und Timer.

Der Event Loop

Planen

Ein Thread, eine Callback-Queue und nicht-blockierende Systemaufrufe.

Das Ökosystem

Erweitern

Die npm registry liefert Frameworks, Bibliotheken und Command-Line-Tools.

Node.js auf einen Blick

Der Kern von Node.js

HTTP Server

Erstelle eine API mit dem integrierten http-Modul oder einem Framework.

Dateisystem

Lese und schreibe Dateien mit der asynchronen fs API.

process und env

Lese Argumente, Umgebungsvariablen und Exit-Codes aus.

Events und Streams

Verarbeite Daten in Chunks und reagiere auf Events, sobald sie auftreten.

Module

Organisiere Code mit ESM import und export.

APIs und Tools

Erstelle REST APIs, GraphQL Server, CLIs und Background Worker.

Eine kurze Geschichte

JavaScript verlässt den Browser

  1. 2009

    Node.js veröffentlicht

    Ryan Dahl lässt JavaScript mit einem event-gesteuerten Modell auf dem Server laufen.

    09
  2. 2011

    npm und Express

    Ein Paketmanager und ein Web-Framework beschleunigen die Adaption.

    11
  3. 2015

    Long-term support

    LTS-Releases und eine Foundation bringen Stabilität für den produktiven Einsatz.

    15
  4. 2017

    async/await

    Asynchroner Server-Code wird wesentlich einfacher zu lesen.

    17
  5. Heute

    Überall

    Die Standard-Runtime für Build-Tools, APIs, Serverless Functions und CLIs.

    Heute

Der vollständige Leitfaden

Node.js Basics: Alles was Sie wissen müssen

Warum Node.js wichtig ist

Node.js ist eine Runtime, die JavaScript außerhalb des Browsers ausführt. Es wurde 2009 veröffentlicht, nutzt die V8-Engine von Chrome und kombiniert diese mit APIs für Dateien, Netzwerke und Prozesse. Dadurch können Entwickler eine einzige Sprache über den gesamten Stack hinweg einsetzen.

Das Hauptmerkmal ist das nicht-blockierende, eventgesteuerte I/O. Anstatt für jede Anfrage einen Thread zu reservieren und zu warten, bis die Festplatte oder das Netzwerk antwortet, delegiert Node die langsame Operation und macht mit anderen Aufgaben weiter. Sobald die Operation abgeschlossen ist, wird ein Callback ausgeführt. Dieses Modell macht Node.js hocheffizient für APIs, Echtzeit-Apps und Tools – es ist derselbe Event Loop, den Sie bereits aus JavaScript im Browser kennen.

JavaScript auf dem Server ausführen

Node bietet dir ein globales process, ein Modulsystem und eine Standardbibliothek. Ein minimaler HTTP-Server benötigt keinerlei Abhängigkeiten.

// server.js
import { createServer } from "node:http";

const server = createServer((req, res) => {
  if (req.url === "/health") {
    res.writeHead(200, { "Content-Type": "application/json" });
    res.end(JSON.stringify({ status: "ok" }));
    return;
  }
  res.writeHead(404).end("Not found");
});

server.listen(process.env.PORT ?? 3000);

Die integrierten Imports mit dem Präfix node: machen deutlich, welche Module direkt von Node stammen. Dieser Server verarbeitet Anfragen, sobald sie eingehen, und blockiert niemals bei I/O-Operationen.

Module

Modernes Node verwendet ES modules, dieselbe import- und export-Syntax wie im Browser.

// math.js
export function add(a, b) {
  return a + b;
}

// app.js
import { add } from "./math.js";

Setze "type": "module" in der package.json, um .js-Dateien als ES modules zu behandeln. Node unterstützt weiterhin CommonJS (require und module.exports), auf das du in älterem Code und vielen Packages stoßen wirst. Neue Projekte sollten ES modules verwenden.

Das Dateisystem

Die Dateisystem-API von Node.js ist in asynchronen und synchronen Varianten verfügbar. Verwenden Sie in Servern die asynchrone API.

// files.js
import { readFile, writeFile } from "node:fs/promises";
import path from "node:path";

const file = path.join(import.meta.dirname, "data.json");
const data = JSON.parse(await readFile(file, "utf8"));

await writeFile(file, JSON.stringify({ ...data, updated: Date.now() }, null, 2));

Das node:path Modul übernimmt das plattformübergreifende Zusammenfügen von Pfaden, und import.meta.dirname gibt das Verzeichnis der aktuellen Datei zurück. Synchrone Funktionen wie readFileSync existieren und sind in Skripten sowie im Startup-Code völlig in Ordnung, sollten jedoch niemals innerhalb eines Request-Handlers verwendet werden.

Umgebung und Konfiguration

Konfigurationen gehören in Umgebungsvariablen, nicht in den Code.

// env.js
const config = {
  port: Number(process.env.PORT ?? 3000),
  databaseUrl: process.env.DATABASE_URL,
  nodeEnv: process.env.NODE_ENV ?? "development",
};

Dadurch bleiben Secrets aus dem Repository fern und derselbe Build kann in der Entwicklung, im Staging und in der Produktion ausgeführt werden. Laden Sie lokale Werte in der Entwicklung aus einer .env-Datei mit einem Tool wie dotenv oder dem integrierten --env-file von Node.js und committen Sie diese Datei niemals.

APIs erstellen

Die meisten Node-Apps nutzen ein Framework für das Routing, Parsing und die middleware. Express ist das am weitesten verbreitete; Fastify ist schneller und schema-orientiert.

// api.js
import express from "express";

const app = express();
app.use(express.json());

app.get("/api/users", async (req, res, next) => {
  try {
    const users = await db.users.findMany();
    res.json(users);
  } catch (error) {
    next(error);
  }
});

app.post("/api/users", async (req, res, next) => {
  try {
    const user = await db.users.create(req.body);
    res.status(201).json(user);
  } catch (error) {
    next(error);
  }
});

app.use((error, req, res, next) => {
  console.error(error);
  res.status(500).json({ message: "Something went wrong" });
});

app.listen(config.port);

Route-Handler sind async-Funktionen, Fehler werden an die middleware weitergeleitet und ein finaler Error-Handler wandelt Exceptions in Responses um. Geben Sie aussagekräftige Status-Codes und Header zurück und lesen Sie unter Web Security mehr über die Validierung von Inputs und den Schutz von Sessions.

Streams, Buffer und Events

Node verarbeitet Daten als Streams, sodass große Payloads nicht vollständig in den Speicher passen müssen.

// stream.js
import { createReadStream } from "node:fs";
import { createServer } from "node:http";

createServer((req, res) => {
  createReadStream("movie.mp4").pipe(res);
}).listen(3000);

Ein Buffer enthält rohe Binärdaten, und ein Event Emitter ermöglicht es Objekten, Events zu veröffentlichen, die von anderen abonniert werden können. Streams und Events sind die Low-Level-Mechanismen hinter einem Großteil der Node-Standardbibliothek. Wenn man diese versteht, wird klar, wie Dateien, Sockets und HTTP unter der Haube funktionieren.

Fehler und Prozesssignale

Nicht abgefangene Fehler können einen Node-Prozess zum Absturz bringen, daher sollten diese bewusst behandelt werden.

// signals.js
process.on("SIGTERM", () => {
  server.close(() => process.exit(0));
});

process.on("unhandledRejection", (reason) => {
  console.error("Unhandled rejection", reason);
});

SIGTERM wird von den meisten Plattformen gesendet, wenn ein Container oder Prozess gestoppt werden soll; wenn Sie dieses Signal behandeln, können Sie laufende Anfragen abschließen, bevor das Programm beendet wird. Globale Handler dienen als Sicherheitsnetz für das Logging und sind kein Ersatz für die Fehlerbehandlung an der Stelle, an der sie auftreten.

Best Practices

  • Verwende async APIs in Request-Handlern und blockiere niemals den Event Loop.
  • Speichere Konfigurationen in Umgebungsvariablen.
  • Validiere und bereinige alle Eingaben auf dem Server.
  • Nutze ES-Module und das node:-Präfix für Built-ins.
  • Zentralisiere das Error Handling in einer middleware.
  • Streame große Dateien, anstatt sie vollständig in den Speicher zu laden.
  • Behandle SIGTERM für einen Graceful Shutdown und stelle einen Health-Endpoint bereit.

Häufige Fehler

  • Verwendung von readFileSync innerhalb eines Request-Handlers, was den Server blockiert.
  • Ausführung von CPU-intensiven Aufgaben im Main Thread.
  • Committen von .env-Dateien oder Hardcoden von Secrets.
  • Vertrauen auf Client-Inputs ohne vorherige Validierung.
  • Ignorieren von unhandled promise rejections.
  • Einlesen großer Dateien vollständig in den Speicher anstatt sie zu streamen.

Wie geht es weiter?

Node.js vervollständigt das Full-Stack-Bild. Verwalte Abhängigkeiten mit npm, verstehe das HTTP-Protokoll, das dein Server spricht, sichere ihn mit Web Security ab und packe ihn mit Docker ein. Baue anschließend eine kleine API mit zwei Routes, einem Datenbankaufruf und einem Error-Handler und deploye diese.

Dateien lesen

Nutze die asynchrone API, damit der Event Loop frei bleibt. Blockierende Aufrufe halten jede andere Anfrage auf, während sie warten.

Bevorzugt
import { readFile } from "node:fs/promises";

const data = await readFile("config.json", "utf8");
const config = JSON.parse(data);
Vermeiden
import { readFileSync } from "node:fs";

// blocks the whole server
// while the disk responds
const data = readFileSync("config.json", "utf8");

Konfiguration

Lese Secrets und umgebungsspezifische Werte aus Umgebungsvariablen, damit dasselbe Image in jeder Umgebung läuft.

Bevorzugt
const port = process.env.PORT ?? 3000;
const dbUrl = process.env.DATABASE_URL;
Vermeiden
const port = 3000;
const dbUrl = "postgres://localhost/prod";
// committed credentials

Häufig gestellte Fragen

Häufig gestellte Fragen

Keep learning

Related topics from the roadmap.

$ Lernen Sie jetzt

Bereit, Node.js Basics zu lernen?

Unser interaktives Tutorial führt Sie Schritt für Schritt durch Node.js Basics — mit Quizzen und echtem Code, den Sie im Browser ausführen können.