Web APIs, todayLab · Alex Harto

WebGPU

The modern GPU on the web: 3D graphics and general-purpose compute with WGSL shaders.

In your browser: checking…Reviewed 1 Oct 2026

WebGL’s successor, designed on top of Vulkan, Metal and Direct3D 12. Besides drawing, it lets you compute on the GPU: simulations, physics, image processing or AI models running in the browser.

It has been in Chrome and Edge since 2023, in Safari since version 26 (September 2025) and in Firefox on Windows since 141; on Apple silicon Macs, since Firefox 147. It is not Baseline yet: Firefox on Linux and Android is missing.

What it is for

  • Real-time particle and fluid simulations
  • Visualising millions of data points
  • On-device AI model inference

Demo

A particle field computed on the GPU with a compute shader every frame. Move the pointer (or your finger) over the canvas to attract them.

Browser support

Limited availability
FeatureDesktopMobile
ChromeEdgeFirefoxSafariChrome AndroidFirefox AndroidSafari iOS
WebGPU (navigator.gpu)1131Chrome: 113 1132Edge: 113 141Partial3Firefox: 141 Partial26Safari: 26 1214Chrome: 121 —Firefox: No26Safari: 26
  1. 1Windows, macOS and ChromeOS since 113; Linux with Intel Gen12+ since 144 and NVIDIA on Wayland since 147. Windows on ARM behind a flag.
  2. 2Same as Chrome on desktop.
  3. 3Windows since 141; macOS on Apple silicon since 145 (Tahoe) and 147 (all versions). Linux, Intel Macs and Android in Nightly only.
  4. 4Android 12+ with Qualcomm or ARM GPUs; Imagination on Android 16+ since 139.

Compatibility generated on every deploy from MDN browser-compat-data 8.1.3 (24 Sep 2026) · web-features 3.40.0 · checked by hand: 1 Oct 2026

Minimal code

<!doctype html>
<meta charset="utf-8">
<title>WebGPU · ejemplo mínimo</title>
<!-- Cómputo en la GPU: duplica ocho números con un shader WGSL y lee el resultado. -->
<pre id="out">…</pre>
<script type="module">
const out = document.querySelector('#out');

if (!navigator.gpu) throw (out.textContent = 'WebGPU no está disponible en este navegador.');
const adapter = await navigator.gpu.requestAdapter();
if (!adapter) throw (out.textContent = 'No hay un adaptador de GPU utilizable.');
const device = await adapter.requestDevice();
device.lost.then((info) => console.warn('GPU perdida:', info.reason, info.message));

const input = new Float32Array([1, 2, 3, 4, 5, 6, 7, 8]);
const storage = device.createBuffer({
  size: input.byteLength,
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
});
device.queue.writeBuffer(storage, 0, input);
const readback = device.createBuffer({
  size: input.byteLength,
  usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,
});

const module = device.createShaderModule({ code: /* wgsl */ `
  @group(0) @binding(0) var<storage, read_write> data: array<f32>;
  @compute @workgroup_size(64)
  fn main(@builtin(global_invocation_id) id: vec3u) {
    if (id.x < arrayLength(&data)) { data[id.x] = data[id.x] * 2.0; }
  }` });
const pipeline = device.createComputePipeline({ layout: 'auto', compute: { module, entryPoint: 'main' } });
const bindGroup = device.createBindGroup({
  layout: pipeline.getBindGroupLayout(0),
  entries: [{ binding: 0, resource: { buffer: storage } }],
});

const encoder = device.createCommandEncoder();
const pass = encoder.beginComputePass();
pass.setPipeline(pipeline);
pass.setBindGroup(0, bindGroup);
pass.dispatchWorkgroups(Math.ceil(input.length / 64));
pass.end();
encoder.copyBufferToBuffer(storage, 0, readback, 0, input.byteLength);
device.queue.submit([encoder.finish()]);

await readback.mapAsync(GPUMapMode.READ);
const result = new Float32Array(readback.getMappedRange().slice(0)); // copia antes de unmap()
readback.unmap();
out.textContent = `[${input}] → [${result}]`;
</script>

What’s new

  1. Firefox 157 adds the TRANSIENT_ATTACHMENT texture usage.
  2. Safari 27 supports clip_distances in WGSL.
  3. Chrome 147: Linux with NVIDIA GPUs on Wayland.
  4. Chrome 146: compatibility mode for OpenGL ES 3.1 GPUs, starting with Android.
  5. Firefox 147 brings it to every macOS version on Apple silicon.
  6. Chrome 144: Linux with Intel Gen12+ GPUs.

Keep in mind

  1. navigator.gpu may exist while requestAdapter() returns null (blocklisted GPU or driver): check both.
  2. Since Chrome 140 an adapter can only be used for one requestDevice(); to recover from device.lost, request a new adapter.
  3. Secure contexts only (HTTPS or localhost). Firefox does not expose it in service workers.

Further reading

Sources