Renderer & Engine Selection
VeloxKit has three rendering backends with very different memory profiles. Understanding how the selection works lets you ship the right binary for your audience.
The numbers
Measured on real apps (2026-05, hello-world / Calculator):
| Backend | Hello World RSS | Calculator RSS | Visual quality | Cold start |
|---|---|---|---|---|
| TinySkia (CPU) | 97 MB | 99 MB | Good | Fastest |
| FemtoVG (OpenGL) | 103 MB | 153 MB | Good | Medium |
| Vello (wgpu compute) | 285 MB | 328 MB | Best | Slowest |
The backend is the dominant cost. The jump from TinySkia to Vello is ~188 MB on hello-world β larger than Electron's entire binary.
How auto works
auto runs after the GPU adapter is created and classifies the hardware into one of four tiers using wgpu::DeviceType and the PCI vendor ID:
No GPU / WARP / llvmpipe β TinySkia
Integrated GPU (Intel UHD, iGPU, Apple Silicon) β TinySkia
Intel Arc discrete GPU (vendor 0x8086, discrete) β FemtoVG
NVIDIA or AMD discrete GPU β VelloThe decision is logged at startup so it's always visible:
[velox] renderMode=auto β skia (Intel(R) UHD Graphics 770, IntegratedGpu)
[velox] renderMode=auto β femtovg (Intel(R) Arc A770 Graphics, DiscreteGpu)
[velox] renderMode=auto β vello (NVIDIA GeForce RTX 4080, DiscreteGpu)VELOX_CPU_RENDER=1 overrides all tiers and forces TinySkia regardless of hardware.
On a typical developer machine (laptop with Intel iGPU), auto picks TinySkia. Vello is only selected when a dedicated NVIDIA or AMD GPU is present.
App persona recommendations
Use this as a starting point when choosing explicitly:
| App persona | Renderer | Notes |
|---|---|---|
| Showcase / portfolio | Vello | Best gradients, shadows, high-density glyphs |
| Indie game (mid-spec) | FemtoVG | Smooth GPU animations, lighter footprint |
| 2D casual game | TinySkia | Fast, low RAM, good enough quality |
| 2D game on weak HW | TinySkia | Sub-100 MB story |
| Productivity app | TinySkia | Most common use case β fast, predictable |
| Productivity on low-RAM laptop | TinySkia | No GPU allocation |
| Settings / dialog app | TinySkia | JS is glue, RAM matters more than polish |
| Dev tool / asset pipeline | TinySkia | Headless-friendly |
| Headless test / CI | TinySkia | No display required |
| Kiosk / arcade machine | TinySkia | Long-running, low-end target |
| 3D content | Vello | Required for 3D Canvas API |
Explicit config
Override auto when you know your target hardware:
// veloxkit.config.ts
export default defineConfig({
window: {
renderMode: 'skia', // always TinySkia β minimum footprint
// renderMode: 'femtovg', // always FemtoVG β GPU animations
// renderMode: 'gpu', // always Vello β max quality
// renderMode: 'auto', // heuristic (default)
},
})Force TinySkia at runtime (useful for CI or debugging):
VELOX_CPU_RENDER=1 veloxkit dev
VELOX_CPU_RENDER=1 veloxkit buildFallback chain
If a backend fails to initialise, VeloxKit falls back automatically:
vello β femtovg β skia β ERROR
femtovg β skia β ERROR
skia β ERROR (cannot render)The fallback is logged so it's never silent.
Edge cases
Hybrid GPU laptops (switchable graphics)
Laptops with both an iGPU and a dGPU let the OS decide which adapter wgpu sees. With PowerPreference::HighPerformance, wgpu usually gets the dGPU. If the OS pins the iGPU, auto will pick TinySkia.
Vulkan on iGPU (Linux)
The Velox GPU adapter probe prefers DX12 on Windows to avoid the Vulkan allocator pre-reserving large pools on iGPU hardware. On Linux with Vulkan + iGPU, auto picks TinySkia which bypasses this entirely.
macOS (Apple Silicon)
Apple Silicon reports as IntegratedGpu (Metal). auto picks TinySkia. Set renderMode: 'femtovg' or 'gpu' explicitly if you want GPU rendering on macOS.
VMs and CI
wgpu::DeviceType::VirtualGpu (VMware, Hyper-V, VirtualBox with GPU passthrough) β TinySkia. Software adapters (no GPU at all) β TinySkia.
Keeping the numbers honest
After each release, re-measure on hello-world and calculator and update this guide if the numbers change. The matrix above reflects measurements from 2026-05. If you add heavy assets or large dependency trees, your app's footprint will differ β use veloxkit dev --perf to see live RSS.