watchGPUDevice
A WebGPU device can be taken away for the same reasons a WebGL context can, and it tells you in a completely different way. WebGL fires an event. WebGPU resolves a promise it handed you when the device was created. Code written for the event never hears the promise, so the canvas stops drawing with nothing thrown and a clean console.
watchGPUDevice tells the runtime when a WebGPU device dies. Hand it a device, and it hands back a function that stops watching.
A loss increments the same generation counter a lost WebGL context does. A scene gate keyed on that counter rebuilds against a device you request fresh, so a recovery path written for WebGL works here with nothing changed. The counter never cared which graphics API died.
Through React Three Fiber you never call this yourself. Spread useRenderQuality's props and the adapter finds the device and watches it for you.
Added in 4.1.0. No WebGPU type packages required: the parameter covers the one field this reads, so a real device satisfies it either way.
◆What your browser exposes
Programmatic device destruction via device.destroy() is intentionally ignored by the runtime to prevent false-positive recovery loops during component unmounting. Testing hardware-level device loss requires driver crash simulation or GPU memory eviction.
Quick start
Request a device, hand it over, stop watching when you tear it down.
Both orders are safe, because a destroyed device is ignored on its reason alone. Stopping first just means the resolution arrives with nothing listening.
Why a destroyed device is ignored
Differentiating between programmatic device destruction and unexpected hardware failure.
In WebGPU, GPUDevice.lost resolves with a GPUDeviceLostInfo structure containing a reason property. When application code intentionally disposes of a device by invoking device.destroy(), reason is set to "destroyed". If the GPU encounters an unrecoverable driver crash, device reset, or memory eviction, reason resolves to "unknown".
Failing to distinguish between intentional teardown and unexpected failure creates an infinite reconstruction loop: disposing of a device during component unmount triggers a context-loss event, which increments the scene generation counter, mounts a replacement, unmounts previous resources, and fires additional loss events.
The runtime coalesces simultaneous device loss events across multiple canvases within a 250ms debounce window. A single GPU reset affecting multiple active contexts increments the generation counter once, avoiding duplicate re-render cycles.
Calling stop() flags the observer as inactive. Because standard Promises cannot be cancelled once attached, the internal listener continues execution upon resolution but suppresses telemetry and recovery dispatches.
API Reference
Syntax
Registers a device as healthy upon initialization and monitors GPUDevice.lost for unexpected hardware failures.
Parameters
| Parameters.field | Type | Default | Description |
|---|---|---|---|
| device | GPUDeviceLike | (none) | Any WebGPU device instance or wrapper exposing a lost Promise adhering to the GPUDevice specification. |
Return Value
Deactivates reporting. Safe to invoke idempotently during unmount or after device loss.
Loss reasons
Evaluation and dispatch policy for GPUDeviceLostInfo reason values.
| Loss reasons.field | Meaning | Runtime Action |
|---|---|---|
| "destroyed" | Intentional disposal via device.destroy(). | Ignored; teardown completes normally. |
| "unknown" | Driver reset, GPU hang, or OS resource reclaim. | Loss reported; scene generation increments. |
| undefined | Implementation resolved without reason metadata. | Treated as unexpected loss; recovery initiated. |
Lifecycle & Invariant Guarantees
- →Teardown vs. Failure Discrimination: Intentional device destruction during component unmount never triggers context recovery rebuilds.
- →Coalesced Driver Reset Handling: Loss events occurring within 250ms are coalesced into a single recovery cycle, preventing multi-canvas cascade rebuilds.
- →Holding a device reports health: Receiving a device ends a recovery. The replacement announcing itself is the signal that the scene is drawable again.
- →A non-conformant promise cannot break the page: The spec says the promise resolves. An implementation that rejects instead reports nothing rather than surfacing an unhandled rejection.
◆Production Examples
Battle-tested production patterns ready to copy directly into your codebase.
The generation is the recovery. A new key means a device requested fresh.
When NOT to use this
Rules & Gotchas
- →Stop watching in the cleanup that destroys the device: A watcher outliving the component that owns the device is how a teardown ends up reported as a failure.
- →Request a new device on a new generation: A lost device cannot be revived. Recovery means requesting another, which is what keying the subtree on generation makes React do.
- →Do not await the lost promise in a render path: It resolves only when the device dies, which on a healthy machine is never.
- →Do not read navigator.gpu as proof of a working device: A blocklisted driver exposes the API and then refuses the adapter, so the request can still fail.