Die Magie: Linux im Browser
Wenn du Terminal Missionen ausprobierst, denkst du vielleicht: “Okay, das ist bestimmt nur eine Animation oder ein Fake-Terminal.”
Nope. Das ist ein echtes Linux-System, das in deinem Browser läuft.
Keine VM auf einem Server. Kein SSH zu irgendeinem Rechner. Das Terminal läuft lokal in deinem Browser, dank einer Technologie namens WebContainer.
Was ist WebContainer?
WebContainer ist eine Technologie von StackBlitz, die Node.js und ein Dateisystem direkt im Browser ausführt.
Das Besondere:
- Läuft komplett client-side, kein Server nötig
- Basiert auf WebAssembly (WASM)
- Hat ein echtes Dateisystem
- Unterstützt npm und Node.js
StackBlitz nutzt das für ihre Online-IDE. Ich nutze es, um euch ein Linux-Terminal zu geben.
Wie funktioniert das technisch?
1. WebAssembly als Basis
WebAssembly (WASM) ist ein Binärformat, das nahezu native Geschwindigkeit im Browser erreicht. Statt JavaScript zu interpretieren, führt der Browser kompilierten Code aus.
Traditionell:
JavaScript wird interpretiert, das ist langsam
Mit WASM:
Kompilierter Code wird direkt ausgeführt, das ist schnell
2. Virtuelles Dateisystem
WebContainer emuliert ein POSIX-kompatibles Dateisystem. Wenn du ls -la tippst, greift das auf ein echtes (virtuelles) Dateisystem zu:
// So mounte ich Dateien in WebContainer
await webcontainer.mount({
'welcome.txt': {
file: { contents: 'Willkommen im Terminal!' }
},
'home': {
directory: {
'visitor': {
directory: {
'.secret': {
file: { contents: 'U3VwZXJTZWNyZXQxMjM=' }
}
}
}
}
}
});
3. Custom Shell statt jsh
WebContainer kommt mit jsh, einer minimalen Shell. Problem: jsh findet keine Scripts in /bin/ wie Bash das tun würde.
Meine Lösung: Eine Custom Node.js Shell, die alle Befehle selbst implementiert:
const commands = {
whoami: () => console.log('visitor'),
pwd: () => console.log(process.cwd()),
ls: (args) => {
const entries = fs.readdirSync('.');
console.log(entries.join(' '));
},
// ... 25+ weitere Befehle
};
Wenn du whoami tippst, führt meine Shell die entsprechende JavaScript-Funktion aus.
Die Herausforderungen
Problem 1: jsh findet keine Befehle
Mein erster Ansatz war, Node.js-Scripts in /bin/ zu legen – wie auf einem echten Linux-System. Hat nicht funktioniert.
Versuch 1: Scripts in /bin/whoami.js … jsh: command not found
Versuch 2: npm bin linking … Immer noch nicht gefunden
Versuch 3: Custom Shell … Funktioniert!
Problem 2: Cross-Origin Isolation
WebContainer braucht spezielle HTTP-Headers:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Ohne diese Headers kein SharedArrayBuffer, ohne SharedArrayBuffer kein WebContainer.
Lösung: Astro Middleware, die diese Headers setzt:
// src/middleware.ts
export function onRequest({ request }, next) {
const response = await next();
response.headers.set('Cross-Origin-Opener-Policy', 'same-origin');
response.headers.set('Cross-Origin-Embedder-Policy', 'require-corp');
return response;
}
Problem 3: Fallback für ältere Browser
Nicht jeder Browser unterstützt WebContainer. Meine Lösung: Ein Mock-System als Fallback.
const canUseWC = canUseWebContainer();
if (!canUseWC) {
// Mock-Modus: Simulierte Befehle
initMockMode(terminal);
} else {
// Echter WebContainer
await initRealMode(terminal);
}
Der Mock-Modus sieht identisch aus, läuft aber ohne WebContainer.
Der Tech-Stack
Für die Technik-Interessierten, hier der komplette Stack:
| Komponente | Technologie |
|---|---|
| Framework | Astro 5.x |
| UI | React 19 + TypeScript |
| Terminal Rendering | xterm.js |
| Linux Runtime | WebContainer API |
| Shell | Custom Node.js Shell |
| Styling | Tailwind CSS + Glassmorphism |
Warum ist das die Zukunft?
Keine Server-Kosten
Traditionelle Code-Playgrounds brauchen Server, die User-Code ausführen. Das kostet Geld und ist ein Sicherheitsrisiko.
Mit WebContainer läuft alles im Browser des Users. Ich zahle nur für statisches Hosting.
Keine Installation
“Installiere erst Docker, dann eine VM, dann Ubuntu…” Das schreckt Anfänger ab.
Mit WebContainer öffnest du einfach den Browser und legst los. Fertig.
Sicher
Was auch immer du im Terminal machst, es bleibt in deinem Browser. Kein Risiko für dein System.
Offline-fähig (theoretisch)
Da alles client-side läuft, könnte man das Ganze offline-fähig machen. Steht auf meiner Roadmap.
Selbst ausprobieren
Du willst WebContainer in deinem eigenen Projekt nutzen? Hier ein minimales Beispiel:
import { WebContainer } from '@webcontainer/api';
// WebContainer starten
const webcontainer = await WebContainer.boot();
// Dateien mounten
await webcontainer.mount({
'index.js': {
file: { contents: 'console.log("Hello World!")' }
}
});
// Script ausführen
const process = await webcontainer.spawn('node', ['index.js']);
// Output lesen
process.output.pipeTo(new WritableStream({
write(data) { console.log(data); }
}));
Ressourcen:
Fazit
WebContainer ist eine Game-Chan… nein, warte, das Wort darf ich nicht benutzen. 😄
WebContainer ist eine bahnbrechende Technologie, die interaktive Tutorials auf ein neues Level hebt. Statt Videos zu schauen, tippst du echte Befehle – und das ohne Risiko.
Probier’s aus: Terminal Missionen starten
Weiterführende Artikel: