Skip to content

Web Development · Browser APIs

WebGPU in 2026: What You Can Build With Browser GPU Compute

WebGPU is now in Chrome, Firefox, and Safari: a general-purpose GPU compute layer, not just graphics, for ML inference, image processing, and simulation.

Anurag Verma

Anurag Verma

8 min read

WebGPU in 2026: What You Can Actually Build With GPU Compute in the Browser

Sponsored

Share

For years, GPU access in the browser meant WebGL. WebGL was designed for 3D graphics in 2009 and was never meant to be a general-purpose compute platform. Using it for machine learning inference or image processing required translating your computation into vertex and fragment shaders, which is roughly as natural as writing a spreadsheet formula in assembly.

WebGPU changes this. It’s a modern GPU API, specified by the W3C GPU for the Web Community Group, designed from scratch with both graphics and compute in mind. It’s available in Chrome (since version 113), Firefox (behind a flag that became default in late 2025), and Safari (enabled by default in Safari 17.4). For most web users today, WebGPU just works. It sits alongside WebAssembly as one of the technologies pushing what a browser tab can do; see our broader look at WebAssembly beyond the browser for the other half of that story.

What WebGPU Gives You

WebGPU gives web developers direct access to compute shaders and a modern graphics pipeline, both unavailable cleanly in WebGL. Compute shaders run arbitrary parallel computation on the GPU for machine learning inference, image processing, and physics simulation, while the graphics API mirrors Vulkan and Metal with explicit resource management instead of WebGL’s global state and driver quirks.

WebGPU exposes two things you couldn’t do cleanly with WebGL:

Compute shaders. A compute shader runs arbitrary parallel computation on the GPU. No triangle rasterization, no fragment pipeline. You write a function that runs thousands of times in parallel, feed it data, and get results back. This is the basis of GPU-accelerated machine learning, image processing, physics simulations, and any other task that benefits from data parallelism.

A saner graphics API. For graphics work, WebGPU’s render pipeline is closer to Vulkan and Metal than to OpenGL. Explicit resource management, no global state, no driver-specific behavior quirks. If you’ve written Vulkan code, WebGPU will feel familiar.

Most of the practical use cases in web development are on the compute side, so that’s where this guide focuses.

Your First Compute Shader

Here’s the minimum needed to run a compute shader in WebGPU. This example multiplies every element in an array by 2:

// Check for WebGPU support
if (!navigator.gpu) {
  throw new Error('WebGPU not supported');
}

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

// Input data
const inputArray = new Float32Array([1, 2, 3, 4, 5, 6, 7, 8]);

// Create a buffer on the GPU
const inputBuffer = device.createBuffer({
  size: inputArray.byteLength,
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
});

// Upload data to the GPU buffer
device.queue.writeBuffer(inputBuffer, 0, inputArray);

// Create an output buffer
const outputBuffer = device.createBuffer({
  size: inputArray.byteLength,
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,
});

// A buffer we can read back from (GPU -> CPU transfer requires MAP_READ)
const readbackBuffer = device.createBuffer({
  size: inputArray.byteLength,
  usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
});

// Write the compute shader in WGSL (WebGPU Shading Language)
const shaderModule = device.createShaderModule({
  code: `
    @group(0) @binding(0) var<storage, read> input: array<f32>;
    @group(0) @binding(1) var<storage, read_write> output: array<f32>;

    @compute @workgroup_size(64)
    fn main(@builtin(global_invocation_id) id: vec3<u32>) {
      let i = id.x;
      if (i < arrayLength(&input)) {
        output[i] = input[i] * 2.0;
      }
    }
  `,
});

// Create the compute pipeline
const pipeline = device.createComputePipeline({
  layout: 'auto',
  compute: { module: shaderModule, entryPoint: 'main' },
});

// Bind the buffers to the pipeline
const bindGroup = device.createBindGroup({
  layout: pipeline.getBindGroupLayout(0),
  entries: [
    { binding: 0, resource: { buffer: inputBuffer } },
    { binding: 1, resource: { buffer: outputBuffer } },
  ],
});

// Record and submit commands
const encoder = device.createCommandEncoder();
const pass = encoder.beginComputePass();
pass.setPipeline(pipeline);
pass.setBindGroup(0, bindGroup);
pass.dispatchWorkgroups(Math.ceil(inputArray.length / 64));
pass.end();

// Copy output to readback buffer
encoder.copyBufferToBuffer(outputBuffer, 0, readbackBuffer, 0, inputArray.byteLength);
device.queue.submit([encoder.finish()]);

// Read results back to CPU
await readbackBuffer.mapAsync(GPUMapMode.READ);
const result = new Float32Array(readbackBuffer.getMappedRange());
console.log([...result]); // [2, 4, 6, 8, 10, 12, 14, 16]
readbackBuffer.unmap();

A few things to note:

  • WGSL (WebGPU Shading Language) is the shader language for WebGPU. It’s statically typed and easier to debug than GLSL.
  • The @workgroup_size(64) means 64 threads run in each workgroup. dispatchWorkgroups(N) launches N workgroups.
  • The CPU-to-GPU and GPU-to-CPU data transfers (writeBuffer and mapAsync) are the main performance cost. Minimize how often you move data across the bus.

Real Use Cases in 2026

Running ML Models in the Browser

The most immediate practical application is running machine learning models without a server. Libraries like @tensorflow/tfjs and onnxruntime-web have had WebGPU backends for over a year. A text embedding model that takes 200ms on CPU takes 8-15ms with WebGPU.

import * as ort from 'onnxruntime-web';

// Force WebGPU backend
const session = await ort.InferenceSession.create('/models/embedding-model.onnx', {
  executionProviders: ['webgpu', 'cpu'],  // fallback to CPU if WebGPU fails
});

const inputTensor = new ort.Tensor('float32', tokenIds, [1, tokenIds.length]);
const output = await session.run({ input_ids: inputTensor });
const embedding = output.last_hidden_state.data;

This pattern is how you build privacy-preserving features where user data never leaves the device: on-device search with semantic embeddings, local content classification, personalization that doesn’t require a server round-trip. For the server-side counterpart to this trend, see our guides on running local LLMs with Ollama and running LLMs on consumer GPUs.

Image Processing

Image convolutions (blur, sharpen, edge detection) are a natural fit for compute shaders. Each output pixel can be computed independently, which is exactly what the GPU excels at.

A Gaussian blur on a 2048x2048 image:

  • JavaScript (CPU): ~400ms
  • WebAssembly (CPU): ~80ms
  • WebGPU compute shader: ~4ms

The speedup isn’t always this dramatic, but image processing consistently benefits from GPU parallelism, especially for real-time effects in video or live camera feeds.

Physics Simulation

For any simulation where N particles interact, the computation scales with N squared. This is a classic case where GPU parallelism pays for itself. Browser-based physics demos and games that run particle systems, cloth simulation, or fluid dynamics benefit from compute shaders more than almost any other web use case. It’s the same class of problem that makes dedicated GPU hardware valuable server-side too; see our GPU chip comparison for how that plays out beyond the browser.

What WebGPU Is Not Good For

It’s worth being specific about the tradeoffs.

WebGPU adds significant startup overhead. Adapter initialization, device creation, pipeline compilation. This takes 50-200ms on a warm cache and can take longer on first load. For a one-off computation, CPU is faster. WebGPU pays off when you’re processing large amounts of data or running the same pipeline many times.

Data transfer is expensive. Moving data between CPU and GPU memory is slow relative to the computation itself. If your workload is “compute a few numbers and display them,” WebGPU is not the answer. It’s best when you can keep data on the GPU for multiple operations before reading results back.

WGSL has a learning curve. It’s a well-designed language, but it’s not JavaScript. If you’re used to working only with the DOM and web APIs, getting comfortable with shaders takes time. The abstractions are different enough that debugging requires a different mental model.

Mobile support is patchy. Desktop Chrome, Firefox, and Safari all support WebGPU well. Mobile is inconsistent. iOS Safari 17.4+ supports it on devices with sufficient GPU capability, but older iPhones and most mid-range Android devices either don’t support it or support it poorly. Always implement a CPU fallback.

Libraries That Hide the Boilerplate

Writing raw WebGPU is verbose. For most production use cases, a library is the right choice:

TensorFlow.js: The WebGPU backend handles ML inference. You write standard TF.js code; the backend handles shader compilation and buffer management.

WONNX: A Rust-based ONNX runtime compiled to WebAssembly that uses WebGPU internally. Faster than onnxruntime-web for some models.

GPU.js: A JavaScript library that compiles JavaScript functions to GLSL/WGSL. Lower ceiling than raw WebGPU but much faster to write.

WebLLM: Specifically for running large language models in the browser via WebGPU. Runs models like Llama 3.2 and Qwen 2.5 locally with WebGPU acceleration.

A Practical Checklist

Before adding WebGPU to a project:

  1. Check if the computation is actually embarrassingly parallel. If each output depends on every other output, the GPU won’t help much.
  2. Estimate the data transfer cost. If you’re sending 100MB to the GPU and reading back 100MB, that alone takes more time than many CPU computations.
  3. Implement the CPU fallback first. Make sure the feature works without WebGPU, then layer in the GPU optimization.
  4. Test on a device without a dedicated GPU. On integrated graphics, WebGPU is faster than CPU for image processing and ML inference, but the gap is smaller.

WebGPU is not a silver bullet for web performance. It solves a specific class of problems: those that benefit from massive parallelism and can tolerate setup overhead. For those problems, the speedup is real and substantial.

Frequently asked questions

What is WebGPU used for?
WebGPU is used for GPU-accelerated compute tasks in the browser that go beyond graphics rendering: running machine learning inference locally (via TensorFlow.js or onnxruntime-web), image processing like blurs and edge detection, and physics simulations where many particles interact in parallel.
Is WebGPU supported in all browsers?
It's supported by default in desktop Chrome (since version 113), Firefox (default since late 2025), and Safari (since 17.4). Mobile support is inconsistent — iOS Safari 17.4+ supports it on capable devices, but many mid-range Android phones and older iPhones don't support it well, so a CPU fallback is necessary.
How much faster is WebGPU than running the same computation on the CPU?
It depends on the workload, but the gains can be large for parallel tasks: a 2048x2048 Gaussian blur drops from about 400ms in plain JavaScript to roughly 4ms with a WebGPU compute shader, and a text embedding model can go from 200ms on CPU to 8-15ms on GPU.
When is WebGPU not worth using?
When the computation isn't embarrassingly parallel, when it's a one-off calculation (the 50-200ms adapter and pipeline setup overhead outweighs the benefit), or when the workload requires moving large amounts of data between CPU and GPU memory relative to how much compute happens on the GPU.
Do I need to learn WGSL to use WebGPU?
Only if you write raw WebGPU compute shaders directly. For most production use cases, libraries like TensorFlow.js, GPU.js, WONNX, or WebLLM handle shader compilation and buffer management, letting you write standard JavaScript, Rust, or TF.js code instead of WGSL.

Sponsored

Sponsored

Discussion

Join the conversation.

Comments are powered by GitHub Discussions. Sign in with your GitHub account to leave a comment.

Sponsored