---
title: Device
description: `Device` is the core wrapper around a raw `GPUDevice`. Use it when you need explicit low-level resource creation (`Buffer`, `Texture`, `Shader`), queue access, readback, and structured WebGPU error scopes.
---

# Device



## Import

```ts
import { Device } from "vgpu/core";
```

## Signature

```ts
import type { Buffer, BufferOptions, Queue, Shader, ShaderInput, Texture, TextureOptions, VGPUError } from "vgpu/core";

interface DeviceOptions {
  readonly isCompatibilityMode?: boolean;
}

declare class Device {
  readonly gpu: GPUDevice;
  readonly adapterInfo: GPUAdapterInfo | null;
  readonly queue: Queue;
  readonly isCompatibilityMode: boolean;
  constructor(gpu: GPUDevice, adapterInfo?: GPUAdapterInfo | null, opts?: DeviceOptions);
  get limits(): GPUSupportedLimits;
  get features(): GPUSupportedFeatures;
  createShader(input: ShaderInput): Shader;
  createTexture(opts: TextureOptions): Texture;
  createBuffer(opts: BufferOptions): Buffer;
  pushErrorScope(filter: GPUErrorFilter): void;
  popErrorScope(): Promise<VGPUError | null>;
  destroy(): void;
  dispose(): void;
}
```

## Parameters

### Constructor

| Param                    | Type                     | Required | Default | Notes                                                                                                               |
| ------------------------ | ------------------------ | -------: | ------- | ------------------------------------------------------------------------------------------------------------------- |
| gpu                      | `GPUDevice`              |        ✔ | —       | Raw WebGPU device. `Device` does not request adapters itself.                                                       |
| adapterInfo              | `GPUAdapterInfo \| null` |        ✖ | `null`  | Stored as `device.adapterInfo`; pass adapter metadata when an adapter provides it.                                  |
| opts                     | `DeviceOptions`          |        ✖ | `{}`    | Core-only options for wrapper behavior.                                                                             |
| opts.isCompatibilityMode | `boolean`                |        ✖ | `false` | Stored as `device.isCompatibilityMode`; adapters set it when they requested WebGPU `featureLevel: "compatibility"`. |

### `createShader(input)`

| Param | Type          | Required | Default | Notes                                                                                                                                    |
| ----- | ------------- | -------: | ------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| input | `ShaderInput` |        ✔ | —       | A WGSL string or a resolved shader object with `.wgsl`. Strings are compiled with `@vgpu/wgsl` before creating the native shader module. |

### `createTexture(opts)`

| Param | Type             | Required | Default | Notes                                                                     |
| ----- | ---------------- | -------: | ------- | ------------------------------------------------------------------------- |
| opts  | `TextureOptions` |        ✔ | —       | Descriptor-first texture options; see `TextureOptions` rows in `Texture`. |

### `createBuffer(opts)`

| Param | Type            | Required | Default | Notes                                                                  |
| ----- | --------------- | -------: | ------- | ---------------------------------------------------------------------- |
| opts  | `BufferOptions` |        ✔ | —       | Descriptor-first buffer options; see `BufferOptions` rows in `Buffer`. |

### Error scopes and teardown

| Param  | Type             | Required | Default | Notes                                                                                 |
| ------ | ---------------- | -------: | ------- | ------------------------------------------------------------------------------------- |
| filter | `GPUErrorFilter` |        ✔ | —       | Passed to `gpu.pushErrorScope(filter)` and also starts a vgpu structured-error scope. |

**Returns:**

* `new Device(...)` returns a wrapper with `.gpu`, `.queue`, `.limits`, `.features`, and resource factory methods.
* `createShader(input)` returns `Shader`.
* `createTexture(opts)` returns `Texture`.
* `createBuffer(opts)` returns `Buffer`.
* `pushErrorScope(filter)`, `destroy()`, and `dispose()` return `void`.
* `popErrorScope()` returns `Promise<VGPUError | null>`; the first captured vgpu error wins, otherwise a native `GPUError` is converted to `VGPU-CORE-VALIDATION`, otherwise `null`.

**Throws:**

* `VGPU-CORE-INVALID-USAGE` when `createBuffer({ size })` receives a non-finite size, `size <= 0`, or an empty `usage` array — pass a positive byte size and at least one buffer usage.
* `VGPU-CORE-VALIDATION` can be returned from `popErrorScope()` when the native WebGPU scope reports a `GPUError` — inspect `.message` and fix the invalid WebGPU descriptor or command.
* Native WebGPU errors may be thrown by `gpu.createShaderModule`, `gpu.createTexture`, `gpu.pushErrorScope`, `gpu.popErrorScope`, or `gpu.destroy`; use error scopes around native validation-sensitive calls.

## Examples

```ts
import { createMockAdapter } from "vgpu/mock";

const device = await createMockAdapter().requestDevice();

const buffer = device.createBuffer({
  label: "positions",
  size: 16,
  usage: ["vertex", "copy_dst", "copy_src"],
});

buffer.write(new Float32Array([0, 1, 2, 3]));
const bytes = await buffer.read(16);
console.log(bytes.byteLength);

device.destroy();
```

```ts
import { createMockAdapter } from "vgpu/mock";

const device = await createMockAdapter().requestDevice();

device.pushErrorScope("validation");
const badBuffer = device.createBuffer({ size: 0, usage: ["copy_dst"] });
const error = await device.popErrorScope();

console.log(badBuffer.options.size, error?.code); // "VGPU-CORE-INVALID-USAGE"
device.dispose();
```

```ts
import { createMockAdapter } from "vgpu/mock";

const device = await createMockAdapter().requestDevice();

if (device.features.has("timestamp-query")) {
  console.log("timestamp queries are available");
}

console.log(device.limits.maxTextureDimension2D);
console.log(device.isCompatibilityMode);

device.destroy();
```

## Notes

* `Device` is intentionally low-level: it does not infer buffer/texture usage from shaders or pipeline state. Provide explicit descriptors.
* Prefer `device.createBuffer(...)` and `device.createTexture(...)` over raw `.gpu` creation when you want vgpu wrappers, readback, lifecycle callbacks, or structured core errors.
* `destroy()` is idempotent and `dispose()` is an alias. Do not call `device.gpu.destroy()` directly unless you intentionally bypass vgpu lifecycle.
* `createBuffer` throws immediately without an error scope, but captures into the current vgpu error scope when one is active.
* `isCompatibilityMode` is only a signal set by the adapter; keep compatibility-specific texture views and WGSL bindings in lockstep yourself.
* **See also:** `Buffer`, `Texture`, `Queue`, `VGPUError`, `VGPUAdapter`.


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)