webPreferences ist das Konfig-Objekt pro BrowserWindow, das die Sicherheits- und Verhaltens-Defaults steuert. Ein paar Optionen sind kritisch — sie entscheiden, ob deine App eine offene Tür für Web-Schwachstellen ist oder eine verriegelte Box. Hier alle wichtigen Optionen mit Defaults und der heute empfohlenen Standardkonfiguration.
Heute empfohlene Default-Konfig
new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true, // Pflicht
sandbox: true, // empfohlen
nodeIntegration: false, // Pflicht (Default false)
nodeIntegrationInWorker: false,
webSecurity: true, // niemals false
allowRunningInsecureContent: false,
experimentalFeatures: false,
navigateOnDragDrop: false
}
});Diese Kombination ist die Sicherheits-Baseline für moderne Electron-Apps. Wer davon abweicht, sollte einen guten Grund haben.
Sicherheits-relevante Optionen
| Option | Default | Was sie tut | Empfehlung |
|---|---|---|---|
contextIsolation | true | Trennt Preload- und Web-Heap | immer true |
sandbox | false (true mit --enable-sandbox) | Renderer in Chromium-Sandbox | immer true |
nodeIntegration | false | require()/process im Renderer | immer false |
nodeIntegrationInWorker | false | Node in Web-Workern | false |
nodeIntegrationInSubFrames | false | Node in iframes | false |
webSecurity | true | CORS und Same-Origin aktiv | niemals false |
allowRunningInsecureContent | false | HTTPS-Seiten dürfen HTTP-Inhalt laden | false |
experimentalFeatures | false | Chromium Experimentelle | false außer Test |
enableBlinkFeatures | '' | Blink-Features (gefährlich) | leer lassen |
Funktionale Optionen
| Option | Default | Was sie tut |
|---|---|---|
preload | null | Pfad zum Preload-Skript |
partition | null | Session-Partition (z. B. 'persist:user1' für separates Cookie-Storage) |
defaultEncoding | 'ISO-8859-1' | Default-Encoding für Renderer |
spellcheck | true | Browser-eigener Spell-Check |
webgl | true | WebGL erlauben |
plugins | false | Browser-Plugins (selten relevant) |
images | true | Bilder laden |
javascript | true | JS überhaupt ausführen |
const userA = new BrowserWindow({
webPreferences: {
partition: 'persist:user-a',
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
sandbox: true
}
});
const userB = new BrowserWindow({
webPreferences: {
partition: 'persist:user-b',
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
sandbox: true
}
});partition macht jedes Fenster zu einem eigenen Session-Container — getrennte Cookies, getrenntes localStorage. Klassischer Use-Case: Multi-Account-Apps.
UI-Verhalten
| Option | Default | Was sie tut |
|---|---|---|
zoomFactor | 1.0 | Initial-Zoom |
backgroundThrottling | true | Reduziert Performance bei minimierten Fenstern |
offscreen | false | Off-Screen-Rendering für Webview-Capture |
enableWebSQL | false | Deprecated WebSQL-Storage |
defaultFontSize | 16 | Default-Font-Größe in Pixel |
backgroundThrottling: false ist sinnvoll für Apps, die im Hintergrund weiter rendern müssen (Live-Dashboards, Audio-Player etc.). Sonst Default lassen — spart Akku.
Klassische Anti-Patterns
new BrowserWindow({
webPreferences: {
nodeIntegration: true, // Hebelt Sandbox/contextIsolation aus
contextIsolation: false, // Preload + Web teilen Heap
webSecurity: false, // CORS aus, alles erlaubt
allowRunningInsecureContent: true
}
});Diese Kombination findet sich in vielen alten Tutorials. Heute: nicht mehr machen. Eine kompromittierte Webseite hat damit volle Kontrolle über das System.
Migration alter Apps
// Schritt 1: nodeIntegration ausschalten, Preload einführen
new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: false
// contextIsolation noch false — alter Renderer-Code geht weiter
}
});
// Schritt 2: Renderer-Code refaktorieren, alle direkten require() entfernen
// Schritt 3: contextIsolation aktivieren
new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: false,
contextIsolation: true
// sandbox noch false — Preload nutzt evtl. fs etc.
}
});
// Schritt 4: Preload aufräumen, Native-Logik in Main verschieben
// Schritt 5: sandbox aktivieren
new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: false,
contextIsolation: true,
sandbox: true
}
});Inkrementell — nicht alles auf einmal. Jeder Schritt einzeln testen.
Interessantes
Defaults haben sich über die Jahre stark gebessert.
In Electron 1-5 war fast alles offen — nodeIntegration: true war Default. Heute (32+) sind die Defaults vernünftig. Wer ein neues Projekt startet und webPreferences weglässt, kriegt schon eine sichere Basis.
partition für Multi-User-Logins.
Wer Apps wie Slack-Multi-Workspace baut: partition: 'persist:user-X'. Cookies und Storage sind getrennt, jedes Fenster fühlt sich an wie eine eigene Browser-Session. Default-Partition heißt einfach '' — wer das mit persist:-prefix mischt, bekommt Verwirrung.
webSecurity: false ist Performance-Maximum, nicht Komfort-Switch.
Wer denkt „CORS-Probleme weg = einfacher": das ist ein Sicherheits-Hammer. Same-Origin-Policy ist aus, Mixed Content erlaubt. Das ist nicht „Komfort", das ist „App offen für Web-Code von außen". Niemals in Production.
backgroundThrottling: false für Live-Apps.
Default ist true — Renderer im Hintergrund werden reduziert (Tickrate, requestAnimationFrame). Bei Audio-Streaming, Live-Dashboards, Echtzeit-Monitoring: explizit aus.
spellcheck nutzt System-Spell-Check.
Default ist true — Chromium-eigener Spell-Check funktioniert in Input-Feldern. Wer das aus UX- oder Privacy-Gründen aus haben will: spellcheck: false. Auf macOS wird sonst die OS-Spell-Check-Sprache verwendet.
Eine webPreferences pro Fenster — Mischung möglich.
Hauptfenster mit voller API, eingebettetes OAuth-Fenster mit minimaleren Rechten. Pro BrowserWindow separat einstellbar. Bei Multi-Window-Apps mit Dritt-Inhalten ein wichtiges Sicherheits-Werkzeug.