go-webengine

A pure-Go, headless web engine — give it a URL, get back an image of the page. HTML/CSS layout and paint with no Chromium and no cgo.

CGO_ENABLED=0 no Chromium · no host web view JavaScript (goja) + real DOM flex · grid · tables · position gradients · box-shadow · SVG amd64 · arm64 · riscv64 · loong64 · ppc64le · s390x ratchet coverage gate measured vs headless Chrome
Documentation GitHub

Modern "render a web page" tooling almost always means shipping a whole browser — Chromium via CDP, a WebView, cgo bindings. go-webengine renders in pure Go. It fetches the page, builds an owned DOM over x/net/html, runs a real CSS cascade (specificity + inheritance, var(), @media, dark-mode), executes the page's JavaScript (goja) against a real DOM, lays out a full box model (block, inline, float, flex, grid, table, position), and paints anti-aliased text (go-opentype), gradients, box-shadows, images and SVG onto an image.RGBA. One static binary, no C toolchain, identical on every OS.

Fetch (go-browserhttp)  →  Parse (x/net/html → dom)  →  Cascade (css: +var()/@media/dark-mode)
     →  JavaScript (js: goja + real DOM + fetch/XHR)
     →  Layout: block · inline · float · flex · grid · table · position (layout)
     ↻   settle loop: JS reads laid-out metrics → re-cascade + re-layout to a bounded fixpoint
     →  Paint: AA text/SVG/gradients/shadows + backgrounds (go-widgets/painter) + images (go-images)
     →  image.RGBA  →  PNG (+ optional link hit-map)

It is the rendering core of the browserproxy remote-browser service and the wasmdesk in-desktop browser. It is not a Chromium replacement and not claimed to match it pixel-for-pixel: example.com renders at near-parity (0.954 SSIM, ~35× faster), JS-heavy and large computed pages are the honest frontier (mean SSIM ≈ 0.69). What works and what does not is documented honestly, page by page and measured against headless Chrome, in the engine's fidelity report and benchmark.

Repositories

engine lib + cli

The rendering core

Fetch a URL → DOM → CSS cascade (var()/@media/dark-mode) → run the page's JavaScript → full box-model layout (flex/grid/tables/position) → paint anti-aliased text, gradients, images and SVG to an image.RGBA / PNG. Pure Go, CGO_ENABLED=0, no Chromium; ships a `render` CLI.

CI coverage ratchet BSD-3-Clause

browserproxy cli

Remote-browser service

Renders pages server-side with the engine and streams frames (plus a click hit-map) to a thin client over a JSON WebSocket protocol, forwarding clicks/scrolls/keys back as navigation. SSRF-guarded. The server half of the wasmdesk in-desktop browser.

CI coverage ratchet BSD-3-Clause

Roadmap

Phase 0–1 · Static render + box modelshipping

HTML parse, a real CSS cascade (specificity + inheritance), and a full box model — block/inline flow, floats, flexbox, CSS grid, tables and position — painted to an image.

Phase 1.9–2.1 · CSS breadth + SVGshipping

var() custom properties, @media, dark-mode, modern colour, gradients, background-image, border-radius, box-shadow, opacity, and pure-Go SVG rasterisation.

Phase 2–2.4 · JavaScript + dynamic rendershipping

goja bound to a real DOM with fetch()/XHR and laid-out-geometry read-back; a settle-then-render loop reflects script-driven DOM mutations, on both the plain and click-hit-map paths.

Phase 3 · browserproxyshipping

A WebSocket remote-browser service (its own repo) renders server-side with the engine and streams frames to the wasmdesk clients/browser front-end.

Phase next · Remaining leversplanned

Closing fidelity residuals (list markers, icon fonts, conic-gradient/filter/mask, SVG filters) and the perf gap on large computed pages. Diminishing returns — mean SSIM ≈ 0.69, example.com at 0.954.

Pure Go, CGO_ENABLED=0, cross-built for all six of Go's 64-bit targets. The pure-logic packages (cascade, line-breaker, box metrics, DOM) are asserted at exact geometry behind a ratchet coverage gate; a committed golden PNG covers the offline paint path. Prior pure-Go browser work (opossum / mycel) was studied but not built on — its layout core is stub-quality; see the survey. BSD-3-Clause throughout.