The order "auto" tries registered backends in — §62's "prefer WebGPU, then
WebGL 2, then an appropriate 2D backend", written out.
"null" is absent on purpose. A headless renderer would "succeed" for every
application whose real backend was unavailable, turning a blank screen into
the automatic outcome; §62's fallback ladder ends at a 2D backend that
genuinely draws, and running headless is an explicit choice
(renderer: "null", or no renderer at all).
Registration order is deliberately not consulted: §62 fixes the
preference, so two applications that register the same backends in different
orders must still resolve "auto" the same way (§33).
"canvas2d" and "svg" are rungs no fourJS package can fill — kept on purpose
@fourjs/render-canvas and @fourjs/render-svg are §102 reserved stubs (one
export each, no Renderer), so from fourJS packages alone these two rungs are
unreachable and "auto" stops at WebGPU/WebGL 2. The rungs stay, because
they are not decoration: they are the published contract an application's
own backend registers into. registerRenderer({ backend: "canvas2d", … })
from consumer code makes resolveRenderer("auto") select it exactly as it
would a first-party backend — measured end to end in dogfood cycle 9A, which
wrote a Canvas 2D backend against published exports only (~120 lines,
35,851 lit pixels / 3 draw calls / 82 triangles against a 0-pixel control)
and an SVG one beside it (83 elements against a 1-element control).
Dropping the rungs to tidy the cosmetic gap would remove a working extension
point; a stub package shipping later fills its own rung with no change here.
The recipe is docs/guides/custom-renderer-backends.md.
The order
"auto"tries registered backends in — §62's "prefer WebGPU, then WebGL 2, then an appropriate 2D backend", written out."null"is absent on purpose. A headless renderer would "succeed" for every application whose real backend was unavailable, turning a blank screen into the automatic outcome; §62's fallback ladder ends at a 2D backend that genuinely draws, and running headless is an explicit choice (renderer: "null", or no renderer at all).Registration order is deliberately not consulted: §62 fixes the preference, so two applications that register the same backends in different orders must still resolve
"auto"the same way (§33)."canvas2d"and"svg"are rungs no fourJS package can fill — kept on purpose@fourjs/render-canvasand@fourjs/render-svgare §102 reserved stubs (one export each, noRenderer), so from fourJS packages alone these two rungs are unreachable and"auto"stops at WebGPU/WebGL 2. The rungs stay, because they are not decoration: they are the published contract an application's own backend registers into.registerRenderer({ backend: "canvas2d", … })from consumer code makesresolveRenderer("auto")select it exactly as it would a first-party backend — measured end to end in dogfood cycle 9A, which wrote a Canvas 2D backend against published exports only (~120 lines, 35,851 lit pixels / 3 draw calls / 82 triangles against a 0-pixel control) and an SVG one beside it (83 elements against a 1-element control). Dropping the rungs to tidy the cosmetic gap would remove a working extension point; a stub package shipping later fills its own rung with no change here. The recipe isdocs/guides/custom-renderer-backends.md.