Browser selber machen
Warum?
Weil alle Browser entweder zu langsam, zu tracking-lastig oder zu vollgestopft sind. Und weil’s Spaß macht.
Was bauen wir?
Einen minimalistischen, extrem schnellen Desktop-Browser auf Chromium-Basis, der standardmäßig Werbung und Tracker blockiert. Mit Electron, TypeScript und dem @cliqz/adblocker-electron.
Schritt 1: Projekt aufsetzen
mkdir my-browser
cd my-browser
npm init -y
npm install electron typescript @cliqz/adblocker-electron @cliqz/adblocker-types cross-fetch
Schritt 2: TypeScript-Konfiguration
Erstelle tsconfig.json:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"outDir": "./dist",
"rootDir": "./src",
"sourceMap": true
},
"include": ["src/**/*"]
}
Schritt 3: Main-Prozess
Erstelle src/main.ts:
import { app, BrowserWindow, session } from 'electron';
import { createElectronBlocker } from '@cliqz/adblocker-electron';
import fetch from 'cross-fetch';
import * as path from 'path';
let mainWindow: BrowserWindow | null = null;
async function createWindow() {
mainWindow = new BrowserWindow({
width: 1200,
height: 800,
frame: true,
webPreferences: {
contextIsolation: true,
nodeIntegration: false,
sandbox: true,
preload: path.join(__dirname, 'preload.js'),
},
});
mainWindow.loadFile(path.join(__dirname, '../renderer/index.html'));
}
async function setupAdBlocker() {
const blocker = await createElectronBlocker({
loadLists: true,
fetchLists: true,
lists: [
'https://easylist.to/easylist/easylist.txt',
'https://easylist.to/easylist/easyprivacy.txt',
],
});
blocker.enableBlockingInSession(session.defaultSession);
}
function setupPrivacy() {
const ses = session.defaultSession;
// Drittanbieter-Cookies blockieren
ses.webRequest.onHeadersReceived((details, callback) => {
callback({
responseHeaders: {
...details.responseHeaders,
'Set-Cookie': undefined,
},
});
});
// Tracker blockieren
ses.webRequest.onBeforeRequest((details, callback) => {
const blockPatterns = [
'google-analytics.com',
'doubleclick.net',
'facebook.com/tr',
'adsystem.com',
'adservice.google.com',
];
const shouldBlock = blockPatterns.some(pattern =>
details.url.includes(pattern)
);
callback(shouldBlock ? { cancel: true } : {});
});
}
app.whenReady().then(async () => {
await setupAdBlocker();
setupPrivacy();
await createWindow();
});
app.on('window-all-closed', () => {
app.quit();
});
Schritt 4: UI
Erstelle renderer/index.html:
<!DOCTYPE html>
<html>
<head>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #1a1a2e; color: #e0e0e0; }
#toolbar {
display: flex; align-items: center; gap: 8px;
padding: 8px 12px; background: #16213e; border-bottom: 1px solid #0f3460;
}
.nav-btn {
background: none; border: none; color: #e0e0e0; cursor: pointer;
padding: 6px 10px; border-radius: 4px; font-size: 16px;
}
.nav-btn:hover { background: #0f3460; }
.nav-btn:disabled { opacity: 0.3; cursor: default; }
#url-bar {
flex: 1; padding: 8px 12px; border: 1px solid #0f3460; border-radius: 6px;
background: #1a1a2e; color: #e0e0e0; font-size: 14px; outline: none;
}
#url-bar:focus { border-color: #e94560; }
#content {
width: 100%; height: calc(100vh - 50px); border: none;
}
</style>
</head>
<body>
<div id="toolbar">
<button id="back" class="nav-btn">←</button>
<button id="forward" class="nav-btn">→</button>
<button id="reload" class="nav-btn">↻</button>
<input type="text" id="url-bar" placeholder="URL eingeben..." value="https://duckduckgo.com" />
</div>
<webview id="content" src="https://duckduckgo.com"></webview>
<script>
const webview = document.getElementById('content');
const urlBar = document.getElementById('url-bar');
const back = document.getElementById('back');
const forward = document.getElementById('forward');
const reload = document.getElementById('reload');
webview.addEventListener('did-navigate', (e) => { urlBar.value = e.url; });
webview.addEventListener('did-navigate-in-page', (e) => { urlBar.value = e.url; });
webview.addEventListener('page-title-updated', (e) => { document.title = e.title + ' — MyBrowser'; });
urlBar.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
let url = urlBar.value.trim();
if (!url.startsWith('http://') && !url.startsWith('https://')) {
url = 'https://' + url;
}
webview.loadURL(url);
}
});
back.addEventListener('click', () => webview.canGoBack() && webview.goBack());
forward.addEventListener('click', () => webview.canGoForward() && webview.goForward());
reload.addEventListener('click', () => webview.reload());
webview.addEventListener('did-start-loading', () => { reload.textContent = '✕'; });
webview.addEventListener('did-stop-loading', () => { reload.textContent = '↻'; });
</script>
</body>
</html>
Schritt 5: Build & Start
In package.json die Scripts anpassen:
{
"scripts": {
"build": "tsc",
"start": "npm run build && electron dist/main.js",
"dev": "tsc && electron dist/main.js"
}
}
Dann:
npm run build
npm start
Ergebnis
Du hast jetzt einen eigenen Browser der:
- ✅ Werbung blockiert (EasyList + EasyPrivacy)
- ✅ Tracker blockiert (Google Analytics, Facebook, Doubleclick)
- ✅ Drittanbieter-Cookies blockiert
- ✅ Sandbox + Context Isolation aktiviert
- ✅ Minimalistisches UI
- ✅ Superschnell
Morvel-Status
Gebaut in: ~30 Minuten Komplexität: Mittel Lernfaktor: Hoch — du verstehst danach wie Browser wirklich funktionieren Nützlichkeit: Sehr hoch — dein eigener Privacy-Browser, komplett unter deiner Kontrolle