Skip to content

0010 — SPICE removal in favor of noVNC

Synced read-only from /home/synnet/mirrors/synvirt-product/docs/adr/0010-spice-removal.md. Edit at the source, not here.

Accepted — implemented in v0.9.0-alpha.1 through v0.9.0-alpha.3.

SynVirt v0.7.x and v0.8.x supported SPICE as the primary VM console protocol via console-gateway, with spice-html5 planned as the browser client and virt-viewer as the native client (.vv download).

By 2026 the SPICE ecosystem upstream is effectively unmaintained:

  • spice-html5 was archived by upstream in 2023; no maintained fork exists.
  • The major commercial open-source virtualization product that drove SPICE adoption pivoted to noVNC for the browser console in 2023.
  • spice-server, spice-protocol, and spice-gtk still receive sporadic commits but have no active feature roadmap.
  • Every browser-console-first hypervisor management surface in this market (open-source or proprietary) defaults to noVNC; SPICE is at most an optional native-client .vv download path.

The maintenance cost of forking and modernising the SPICE stack (spice-html5 + spice-gtk patches + spice-server) is incompatible with SynVirt’s resourcing.

Remove all SPICE support from SynVirt. The single supported browser console protocol is VNC, served via noVNC over WebSocket through console-gateway. The native virt-viewer .vv download path is also removed.

Concretely:

  • Browser console: @novnc/novnc 1.7+ in web-ux-v2, served from a /console/vnc/:vm_uuid?ticket=… WebSocket endpoint in console-gateway.
  • VM domain XML graphics: <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1'/>.
  • Default video device: virtio-vga for modern guests, std-vga (<model type='vga'/>) fallback for legacy guests (Win XP, Win 2000, pre-2010 Linux). QXL is removed entirely.
  • Guest tools ISO: virtio-win drivers + qemu-guest-agent only. spice-guest-tools, spice-vdagent, and qxlwddm are removed.
  • Imported VMs (migrator): domain XML is sanitised at render time. <graphics type='spice'>, <channel type='spicevmc'>, <redirdev type='spicevmc'>, <audio type='spice'>, and <video><model type='qxl'> are stripped and replaced with VNC + virtio-vga. The sanitiser runs as belt-and-suspenders in crates/migrator/src/xml_sanitizer.rs.
  • Console decision matrix (crates/daemon/src/console/recommend.rs): the four-backend matrix collapses to three (Rdp, Vnc, Serial). Every former SPICE fallback now picks Vnc — the host-side QEMU framebuffer proxied by console-gateway. Operator-provided console policies that named SPICE silently degrade to VNC at boot.
  • Single console code path. Less surface area, lower maintenance burden.
  • Aligned with industry direction across both open-source and commercial hypervisor products.
  • Smaller guest-tools ISO (~50% size reduction); faster build pipeline.
  • No dependency on archived/unmaintained upstream JS clients.
  • Loss of features that SPICE provided and noVNC does not match natively at the same quality:
    • Audio passthrough — SPICE had bidirectional audio; noVNC has none.
    • USB redirection — SPICE had transparent USB redirect; noVNC has none.
    • Multi-monitor — SPICE had native multi-monitor; noVNC scales a single viewport.
    • Lower-bandwidth deltas — the SPICE protocol was more efficient than VNC for desktop graphics.
  • VMs imported with SPICE-only XML need to be either re-imported via the migrator (which sanitises) or manually reconfigured with synvirt vm redefine-xml.

WebRTC-based console (host-side framebuffer capture via qemu -display dbus, encoded with GStreamer + webrtcbin, peer-to-peer to browser) is the most likely path to recover the SPICE feature parity. Evaluation deferred to post-v1.0. WebRTC is explicitly NOT a SPICE-style coexistence path — it would replace noVNC if it ships, not run alongside it.

  1. Modernise spice-html5 ourselves — fork, port to TypeScript, add WebCodecs decoding. Rejected: 4–5 weeks of work to maintain a protocol the rest of the industry has moved away from.
  2. Apache Guacamole as console backend — adds clipboard / audio / file-transfer over WebSocket. Rejected: heavier deployment (guacd daemon, Java for full server) and still uses VNC under the hood, so the differentiator vs plain noVNC is incremental for SMB targets.
  3. WebRTC console now — real differentiator but 4 weeks of integration work that delays v1.0 GA. Deferred to post-v1.0.
  • v0.9.0-alpha.1 — noVNC implementation deployed (crates/console-gateway/src/vnc/, web-ux-v2’s VncConsoleView).
  • v0.9.0-alpha.2 — SPICE removal from console-gateway, daemon, vm_profiles, web-ux-v2. Brand color realignment to #0566C1.
  • v0.9.0-alpha.3 — Migrator XML sanitiser, guest-tools-iso cleanup, iso-builder cleanup, this ADR.
  • crates/migrator/src/xml_sanitizer.rs — sanitiser implementation.
  • crates/daemon/src/console/recommend.rs — collapsed decision matrix.