<electrobun-wgpu>
<electrobun-wgpu> embeds a native WGPU-backed surface inside a webview layout. It behaves like a DOM element but renders via a real GPU surface layered above the host view, with optional masking and passthrough for punch‑through UI.
When To Use It
- Compositing high-performance GPU content with a web UI (editors, game tools, IDEs).
- Running Bun-side WGPU rendering while keeping HTML/CSS for layout.
- Mixing native GPU surfaces with webview content without a single WebGL canvas.
If your rendering is simple and you don’t need Bun‑side control or native surface layering, a standard <canvas> inside the webview is still the simplest option.
Platform Notes
On Linux, passthrough and mask punch-through behavior for <electrobun-wgpu> is not supported inside transparent BrowserWindows. Transparent CEF windows use offscreen rendering painted into the parent X11 window, while <electrobun-wgpu> is a separate native child window. The WGPU surface can render and resize correctly, but X11 cannot reliably hit-test through that child surface into the offscreen-rendered host DOM.
For punch-through UI on Linux, use a non-transparent window, keep the interactive HTML outside the WGPU surface, or render the GPU content into a normal in-webview canvas when that composition model is required.
Basic Usage
// In your webview HTML<electrobun-wgpu id="gpu"></electrobun-wgpu>
// In Bun (RPC handler), create a WGPU surface for the view ID// and render via WGPU.native or webgpu.createContext(...)API
const wgpu = document.querySelector("electrobun-wgpu");
// Propertiesconsole.log(wgpu.wgpuViewId);console.log(wgpu.transparent, wgpu.passthroughEnabled, wgpu.hidden);
// Methodswgpu.toggleTransparent(true);wgpu.togglePassthrough(true);wgpu.toggleHidden(false);wgpu.syncDimensions(true);
// Maskswgpu.addMaskSelector("#hud");wgpu.removeMaskSelector("#hud");
// Eventswgpu.on("ready", (evt) => { console.log("WGPU view ready", evt.detail);});The wgpuViewId is the native view identifier. Pass it to your Bun process to create a surface for that view.
Lifecycle + Resize
WebGPU surfaces must be reconfigured on size changes. When your WGPU view or window resizes, update the surface config and re-create any size-dependent resources.
// Bun-side render loop exampleconst ctx = webgpu.createContext(win);let size = win.getSize();
function resizeIfNeeded() { const next = win.getSize(); if (next.width !== size.width || next.height !== size.height) { size = next; ctx.configure({ device, format: webgpu.navigator.getPreferredCanvasFormat(), alphaMode: "premultiplied", size: [size.width, size.height], }); }}Call syncDimensions() after any DOM layout changes so the native view tracks the element bounds.