mirror of
https://github.com/mileswolfallen2/miles-web.git
synced 2026-09-08 11:23:17 +00:00
316 lines
15 KiB
HTML
316 lines
15 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Gelectron | Miles Wolf Allen</title>
|
|
<meta name="description" content="Gelectron — drop-in replacement for Electron using native web views (WKWebView / WebView2 / WebKitGTK) instead of bundling Chromium. Just run gelectron . instead of electron .">
|
|
<link rel="canonical" href="https://milesallen.site/projects/gelectron.html">
|
|
<meta property="og:title" content="Gelectron | Miles Wolf Allen">
|
|
<meta property="og:description" content="Gelectron — drop-in replacement for Electron using native web views (WKWebView / WebView2 / WebKitGTK) instead of bundling Chromium.">
|
|
<meta property="og:image" content="https://milesallen.site/og.png">
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
|
<link rel="icon" type="image/png" href="../favicon.png">
|
|
<link rel="stylesheet" href="style.css">
|
|
</head>
|
|
<body>
|
|
<div class="cursor-dot" id="cursorDot"></div>
|
|
<div class="cursor-ring" id="cursorRing"></div>
|
|
<div class="progress-bar" id="progressBar"></div>
|
|
<button class="theme-toggle" id="themeToggle" aria-label="Toggle theme"></button>
|
|
<div class="shortcut-modal" id="shortcutModal">
|
|
<div class="shortcut-card">
|
|
<h3>Keyboard Shortcuts</h3>
|
|
<div class="shortcut-row"><span>Go Home</span><kbd>H</kbd></div>
|
|
<div class="shortcut-row"><span>Go to GitHub</span><kbd>G</kbd></div>
|
|
<div class="shortcut-row"><span>Toggle theme</span><kbd>T</kbd></div>
|
|
<div class="shortcut-row"><span>Show shortcuts</span><kbd>?</kbd></div>
|
|
<div class="close-hint">Press Esc or ? to close</div>
|
|
</div>
|
|
</div>
|
|
<div class="flash" id="flash"></div>
|
|
<div class="toast-stack" id="toastStack"></div>
|
|
<nav class="mobile-nav">
|
|
<a href="../index.html">Home</a>
|
|
<a href="fedl.html">FEDL</a>
|
|
<a href="gelectron.html" class="active">Gelectron</a>
|
|
<a href="omniemu.html">OmniEmu</a>
|
|
<a href="command-move.html">CommandMove</a>
|
|
<a href="https://github.com/mileswolfallen2" target="_blank">GitHub</a>
|
|
</nav>
|
|
|
|
<div class="container">
|
|
<nav>
|
|
<a href="../index.html" class="nav-logo"><span class="logo-dot"></span> milesallen</a>
|
|
<div class="nav-links">
|
|
<a href="../index.html#about">About</a>
|
|
<a href="../index.html#skills">Skills</a>
|
|
<a href="../index.html#projects">Projects</a>
|
|
<a href="../index.html#contact">Contact</a>
|
|
</div>
|
|
</nav>
|
|
|
|
<section class="project-hero">
|
|
<div class="breadcrumb">
|
|
<a href="../index.html">Home</a>
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"/></svg>
|
|
<span>Gelectron</span>
|
|
</div>
|
|
|
|
<h1>Gelectron</h1>
|
|
<p class="tagline">Drop-in replacement for Electron using native web views (WKWebView / WebView2 / WebKitGTK) instead of bundling Chromium. Just run gelectron . instead of electron .</p>
|
|
|
|
<div class="project-meta-bar">
|
|
<a href="https://github.com/mileswolfallen2/gelectron" class="meta-chip primary" target="_blank">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 00-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0020 4.77 5.07 5.07 0 0019.91 1S18.73.65 16 2.48a13.38 13.38 0 00-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 005 4.77a5.44 5.44 0 00-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 009 18.13V22"/></svg>
|
|
View on GitHub
|
|
</a>
|
|
<a href="https://gelectron.milesallen.site/" class="meta-chip" target="_blank">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 014 10 15.3 15.3 0 01-4 10 15.3 15.3 0 01-4-10 15.3 15.3 0 014-10z"/></svg>
|
|
Website
|
|
</a>
|
|
<span class="meta-chip" style="border-color: #e6a817; color: #e6a817;">Early Development</span>
|
|
<span class="meta-chip">Rust + Node.js</span>
|
|
<span class="meta-chip">MIT License</span>
|
|
</div>
|
|
<div class="stats-bar">
|
|
<div class="stat-item">
|
|
<div class="stat-value accent" id="gh-stars">--</div>
|
|
<div class="stat-label">Stars</div>
|
|
</div>
|
|
<div class="stat-item">
|
|
<div class="stat-value green" id="gh-forks">--</div>
|
|
<div class="stat-label">Forks</div>
|
|
</div>
|
|
<div class="stat-item">
|
|
<div class="stat-value orange" id="gh-issues">--</div>
|
|
<div class="stat-label">Issues</div>
|
|
</div>
|
|
<div class="stat-item">
|
|
<div class="stat-value" id="gh-lang">--</div>
|
|
<div class="stat-label">Language</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="reveal">
|
|
<div class="section-divider"></div>
|
|
<h2 class="section-title">Features</h2>
|
|
<p class="section-subtitle">Why Gelectron exists</p>
|
|
|
|
<div class="feature-grid">
|
|
<div class="feature-card">
|
|
<h3>
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 5v14M5 12h14"/></svg>
|
|
Drop-in Replacement
|
|
</h3>
|
|
<p>Run gelectron . instead of electron . and your app just works. Same Node.js code, same require('electron') imports, zero changes needed.</p>
|
|
</div>
|
|
<div class="feature-card">
|
|
<h3>
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 10h-1.26A8 8 0 109 20h9a5 5 0 000-10z"/></svg>
|
|
Native Web Views
|
|
</h3>
|
|
<p>Uses the OS-native renderer on every platform — WKWebView on macOS/iOS, WebView2 on Windows, WebKitGTK on Linux. No bundled browser engine.</p>
|
|
</div>
|
|
<div class="feature-card">
|
|
<h3>
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
|
|
Electron API Compat
|
|
</h3>
|
|
<p>Implements core Electron APIs: app, BrowserWindow, ipcMain/ipcRenderer, Menu, Tray, Dialog, Shell, Notification, nativeImage, contextBridge, and more.</p>
|
|
</div>
|
|
<div class="feature-card">
|
|
<h3>
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.66 0 3-4.03 3-9s-1.34-9-3-9m0 18c-1.66 0-3-4.03-3-9s1.34-9 3-9"/></svg>
|
|
Smaller Binaries
|
|
</h3>
|
|
<p>No Chromium bundle means binaries are a fraction of Electron's size. Rust static linking keeps them lean. No more 150MB+ apps.</p>
|
|
</div>
|
|
<div class="feature-card">
|
|
<h3>
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
|
|
Lower Memory
|
|
</h3>
|
|
<p>Native web views don't need a separate Chromium process per window. Less overhead, less RAM, snappier feel. Your users will notice.</p>
|
|
</div>
|
|
<div class="feature-card">
|
|
<h3>
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.7 6.3a1 1 0 000 1.4l1.6 1.6a1 1 0 001.4 0l3.77-3.77a6 6 0 01-7.94 7.94l-6.91 6.91a2.12 2.12 0 01-3-3l6.91-6.91a6 6 0 017.94-7.94l-3.76 3.76z"/></svg>
|
|
Built with Rust
|
|
</h3>
|
|
<p>Core engine written in Rust for safety and performance. N-API addon bridges Rust and Node.js seamlessly.</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="reveal">
|
|
<div class="section-divider"></div>
|
|
<h2 class="section-title">Tech Stack</h2>
|
|
<ul>
|
|
<li>Rust (core engine, N-API addon)</li>
|
|
<li>Node.js (CLI, Electron compat layer)</li>
|
|
<li>Servo (rendering engine)</li>
|
|
<li>winit (window management)</li>
|
|
<li>muda (native menus)</li>
|
|
<li>tray-icon (system tray)</li>
|
|
<li>rfd (file dialogs)</li>
|
|
<li>Stylo (CSS engine)</li>
|
|
<li>WebRender (GPU compositor)</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section class="reveal">
|
|
<div class="section-divider"></div>
|
|
<h2 class="section-title">Status</h2>
|
|
<div class="desc-text">
|
|
<p>Gelectron is in very early development. This is an experiment — a proof of concept that Electron apps can run using native web views instead of bundling Chromium. Many Electron APIs are currently stubs or incomplete. Some things will break. Some things don't exist yet.</p>
|
|
<p>The goal right now isn't to replace Electron for production apps. It's to explore whether this is possible, learn how Electron's internals work, and build a foundation that could grow into something real.</p>
|
|
<p>If you're curious, try it out with a simple Electron app. If you find bugs, open an issue. If you want to contribute, even better.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="reveal">
|
|
<div class="section-divider"></div>
|
|
<h2 class="section-title">Known Limitations</h2>
|
|
<ul>
|
|
<li>Servo is still in active development; some web APIs may be missing</li>
|
|
<li>electron-updater requires custom implementation (not yet included)</li>
|
|
<li>Some Electron APIs are stubs</li>
|
|
<li>Native menu integration is platform-dependent</li>
|
|
<li>Auto-updater not yet implemented</li>
|
|
<li>Single-window only in initial version</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section class="reveal">
|
|
<div class="section-divider"></div>
|
|
<h2 class="section-title">Roadmap</h2>
|
|
<ul>
|
|
<li>Full Servo integration</li>
|
|
<li>Multi-window support</li>
|
|
<li>Custom protocol handlers (gelectron://)</li>
|
|
<li>Auto-updater implementation</li>
|
|
<li>DevTools integration</li>
|
|
<li>Build/package tools for distribution</li>
|
|
<li>App sandboxing</li>
|
|
<li>Performance optimizations</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section class="reveal">
|
|
<div class="cta-group">
|
|
<a href="https://github.com/mileswolfallen2/gelectron" class="meta-chip primary" target="_blank">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 00-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0020 4.77 5.07 5.07 0 0019.91 1S18.73.65 16 2.48a13.38 13.38 0 00-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 005 4.77a5.44 5.44 0 00-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 009 18.13V22"/></svg>
|
|
View on GitHub
|
|
</a>
|
|
<a href="../index.html#projects" class="meta-chip">Back to Projects</a>
|
|
</div>
|
|
</section>
|
|
|
|
<footer>
|
|
<div class="footer-links" style="margin-bottom: 12px;">
|
|
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
|
<span style="color:var(--muted);margin:0 8px;">·</span>
|
|
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
|
<span style="color:var(--muted);margin:0 8px;">·</span>
|
|
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
|
<span style="color:var(--muted);margin:0 8px;">·</span>
|
|
<a href="../experiments.html" style="color:var(--accent);text-decoration:none;">Internet History</a>
|
|
</div>
|
|
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
|
</footer>
|
|
</div>
|
|
<script>
|
|
fetch('https://api.github.com/repos/mileswolfallen2/gelectron')
|
|
.then(r => r.json())
|
|
.then(d => {
|
|
if (d.stargazers_count != null) document.getElementById('gh-stars').textContent = d.stargazers_count;
|
|
if (d.forks_count != null) document.getElementById('gh-forks').textContent = d.forks_count;
|
|
if (d.open_issues_count != null) document.getElementById('gh-issues').textContent = d.open_issues_count;
|
|
if (d.language) document.getElementById('gh-lang').textContent = d.language;
|
|
})
|
|
.catch(() => {});
|
|
const observer = new IntersectionObserver((entries) => {
|
|
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('visible'); });
|
|
}, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
|
|
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
|
|
</script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/gsap.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/ScrollTrigger.min.js"></script>
|
|
<script>
|
|
gsap.registerPlugin(ScrollTrigger);
|
|
|
|
// Hero entrance
|
|
const heroTl = gsap.timeline({ defaults: { ease: 'power3.out' } });
|
|
heroTl
|
|
.from('.breadcrumb', { x: -30, opacity: 0, duration: 0.6 })
|
|
.from('.project-hero h1', { y: 50, opacity: 0, duration: 0.8 }, '-=0.3')
|
|
.from('.tagline', { y: 30, opacity: 0, duration: 0.7 }, '-=0.4')
|
|
.from('.meta-chip', { y: 20, opacity: 0, scale: 0.8, duration: 0.4, stagger: 0.06 }, '-=0.3')
|
|
.from('.stats-bar', { y: 30, opacity: 0, duration: 0.6 }, '-=0.2')
|
|
.from('.stat-item', { y: 20, opacity: 0, scale: 0.9, duration: 0.4, stagger: 0.08, ease: 'back.out(1.5)' }, '-=0.3');
|
|
|
|
// Nav entrance
|
|
gsap.from('nav', { y: -20, opacity: 0, duration: 0.6, ease: 'power2.out' });
|
|
|
|
// Section titles
|
|
document.querySelectorAll('.section-title').forEach(title => {
|
|
gsap.from(title, {
|
|
scrollTrigger: { trigger: title, start: 'top 85%' },
|
|
y: 30, opacity: 0, duration: 0.7, ease: 'power3.out'
|
|
});
|
|
});
|
|
|
|
// Section dividers
|
|
document.querySelectorAll('.section-divider').forEach(div => {
|
|
gsap.from(div, {
|
|
scrollTrigger: { trigger: div, start: 'top 90%' },
|
|
width: 0, duration: 0.6, ease: 'power2.out'
|
|
});
|
|
});
|
|
|
|
// Feature cards stagger
|
|
document.querySelectorAll('.feature-grid').forEach(grid => {
|
|
gsap.from(grid.querySelectorAll('.feature-card'), {
|
|
scrollTrigger: { trigger: grid, start: 'top 85%' },
|
|
y: 50, opacity: 0, scale: 0.9, duration: 0.6, stagger: 0.1, ease: 'power3.out'
|
|
});
|
|
});
|
|
|
|
// Tech badges
|
|
document.querySelectorAll('.tech-stack').forEach(stack => {
|
|
gsap.from(stack.querySelectorAll('.tech-badge'), {
|
|
scrollTrigger: { trigger: stack, start: 'top 88%' },
|
|
y: 20, opacity: 0, scale: 0.8, duration: 0.4, stagger: 0.05, ease: 'back.out(1.5)'
|
|
});
|
|
});
|
|
|
|
// Tables
|
|
document.querySelectorAll('.table-wrapper').forEach(wrapper => {
|
|
gsap.from(wrapper, {
|
|
scrollTrigger: { trigger: wrapper, start: 'top 85%' },
|
|
y: 40, opacity: 0, duration: 0.7, ease: 'power3.out'
|
|
});
|
|
});
|
|
|
|
// Code blocks
|
|
document.querySelectorAll('code-block').forEach(block => {
|
|
gsap.from(block, {
|
|
scrollTrigger: { trigger: block, start: 'top 88%' },
|
|
y: 30, opacity: 0, duration: 0.6, ease: 'power3.out'
|
|
});
|
|
});
|
|
|
|
// Footer
|
|
gsap.from('footer', {
|
|
scrollTrigger: { trigger: 'footer', start: 'top 95%' },
|
|
opacity: 0, duration: 0.8
|
|
});
|
|
|
|
window.addEventListener('load', () => ScrollTrigger.refresh());
|
|
</script>
|
|
<script src="script.js"></script>
|
|
</body>
|
|
</html> |