LabHub

Blog

WebGPU & WGSL Ecosystem 2026 — Chrome / Safari / Firefox All GA / wgpu / naga / Tint / Three.js / Babylon / WebLLM / Transformers.js Deep Dive

한국어English日本語

1. The 2026 WebGPU Map — All Three Browsers GA

For more than a decade, browser graphics lived on WebGL 1.0 (2011) and WebGL 2.0 (2017). In 2026 the next-generation standard has finally arrived. Chrome 113 (May 2023), Safari 18 (Sept 2024) and Firefox 141 (Aug 2025) — every evergreen browser supports WebGPU as stable.

WebGPU is not "just a faster WebGL."

As of May 2026 the answer to "should we use WebGPU?" is simple. For a new project, start with WebGPU and keep WebGL as a fallback. This article walks through the spec, browsers, WGSL, compilers, libraries and ML applications, one layer at a time.

Not a single line of code in this article uses a polyfill. Everything targets the stable features of evergreen browsers as of May 2026.


2. The WebGPU Spec — From Working Draft to Candidate Recommendation

Where the spec lives

WebGPU is driven by W3C's GPU for the Web Working Group. Apple (WebKit), Google (Chrome / Dawn), Mozilla (Firefox / wgpu), Microsoft and Intel are joint editors.

Hitting CR means WPT (Web Platform Tests) coverage is sufficient and implementation interoperability has been demonstrated. It is no longer a "works on one browser only" thing.

Two axes of the spec

  1. WebGPU API — the JavaScript interface for talking to the GPU (device / queue / pipeline / binding)
  2. WGSL — the shading language spec for writing vertex / fragment / compute shaders

The two specs are managed as separate documents but evolve together. The stable feature set at CR includes:

Proposals queuing up after CR

CR is not the end, it is the beginning. Expect these extensions to land in 2026 and 2027.


3. Browser Support — Chrome 113 / Safari 18 / Firefox 141

Chrome — May 2023 GA

Chrome 113 was the first GA. Available on macOS / Windows / ChromeOS / Android. Linux stayed behind a flag for a while and gradually flipped on through 2024. Chrome's backend is Google's own Dawn (C++).

Safari — September 2024 GA

Safari 18 and iOS 18 brought GA. WebKit's backend is its own implementation. macOS / iOS / iPadOS / visionOS all run on Metal. The spatial-computing graphics layer of visionOS is also drivable through WebGPU.

Firefox — August 2025 GA

Firefox 141 was the final GA. The backend is wgpu (Mozilla / gfx-rs, Rust). The compiler is naga (WGSL / SPIR-V / GLSL / MSL / HLSL cross-compiler, also Rust).

Feature detection

if (!navigator.gpu) {
  throw new Error('WebGPU not supported by this browser')
}

const adapter = await navigator.gpu.requestAdapter()
if (!adapter) {
  throw new Error('No GPU adapter available')
}

const device = await adapter.requestDevice({
  requiredFeatures: ['timestamp-query'],
  requiredLimits: {
    maxStorageBufferBindingSize: 1024 * 1024 * 1024,
  },
})

A missing adapter typically means (a) the browser does not support WebGPU, (b) the GPU driver is too old or (c) the user blocked it via policy. All three are common in the wild, so always wire up a fallback path.

Coexistence with WebGL

WebGPU does not completely replace WebGL. Even in 2026 WebGL 1 and 2 are needed for (1) legacy device support, (2) low-power mobile devices and (3) WebView / WKWebView embedding. In practice you keep both backends.


4. WGSL — The WebGPU Shading Language

Why not GLSL?

GLSL syntax dates back to the OpenGL era (2004). It does not match the explicitness, safety and tooling friendliness expected from modern graphics APIs. WGSL is a new shading language with Rust-flavoured syntax, co-designed by Apple, Google and Mozilla.

Hello triangle in WGSL

struct VsIn {
  @location(0) position: vec3<f32>,
  @location(1) color: vec3<f32>,
}

struct VsOut {
  @builtin(position) clip_position: vec4<f32>,
  @location(0) color: vec3<f32>,
}

@vertex
fn vs_main(input: VsIn) -> VsOut {
  var out: VsOut;
  out.clip_position = vec4<f32>(input.position, 1.0);
  out.color = input.color;
  return out;
}

@fragment
fn fs_main(input: VsOut) -> @location(0) vec4<f32> {
  return vec4<f32>(input.color, 1.0);
}

Highlights compared to GLSL.

Compute shaders — GPGPU as a first-class citizen

@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 cs_main(@builtin(global_invocation_id) gid: vec3<u32>) {
  let i = gid.x;
  if (i >= arrayLength(&input)) {
    return;
  }
  output[i] = input[i] * 2.0;
}

This 16-line compute shader unlocks what WebGL never delivered: general-purpose GPU compute as a web standard. ML inference, particle simulation, image processing, sorting and prefix sums — they all start here.

Memory address spaces

Address spacePurposeExample
storageLarge buffers (read / read_write)Vertex / particle data
uniformSmall constants (read only)Camera matrix
workgroupShared memory within a workgroupScratch for reductions
privateFunction-localMostly compiler-managed

The explicit address spaces expose the GPU memory hierarchy directly. Much more honest than the GLSL uniform keyword.


5. wgpu (Rust) — Mozilla / gfx-rs's Portable WebGPU

What is wgpu?

wgpu is a WebGPU implementation written in Rust by Mozilla and the gfx-rs community. It plays two roles.

  1. Firefox's backend — Firefox WebGPU is powered by wgpu
  2. A native library — letting Rust (or C / C++ / Python) consume the WebGPU API as a portable layer

The second role is the real story: it means you can use the WebGPU spec on native applications as well.

wgpu's backends

wgpu (Rust crate)
├─ Vulkan   (Linux / Android / Windows / macOS via MoltenVK)
├─ Metal    (macOS / iOS)
├─ DirectX 12 (Windows)
├─ OpenGL ES 3 (legacy device fallback)
└─ WebGPU (browser wasm builds)

The same code compiles for Linux native, Mac native, Windows native and browser wasm — five targets from one source tree.

A small wgpu example (Rust)

use wgpu::util::DeviceExt;

async fn run() {
    let instance = wgpu::Instance::default();
    let adapter = instance
        .request_adapter(&wgpu::RequestAdapterOptions::default())
        .await
        .unwrap();
    let (device, queue) = adapter
        .request_device(&wgpu::DeviceDescriptor::default(), None)
        .await
        .unwrap();

    let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
        label: Some("triangle.wgsl"),
        source: wgpu::ShaderSource::Wgsl(include_str!("triangle.wgsl").into()),
    });

    // ... pipeline / bind groups / draw
}

The Rust game engine Bevy, the GUI framework iced and the embedded graphics library Lyon are all built on wgpu. The WebGPU spec has effectively become the baseline for Rust native apps.

Who uses wgpu?


6. naga + Tint — Two WGSL Compilers in the Family

naga (Rust, gfx-rs)

naga is the shader translation toolkit that grew up alongside wgpu.

# Convert WGSL to Metal Shading Language
cargo install naga-cli
naga shader.wgsl shader.metal

# Convert WGSL to SPIR-V
naga shader.wgsl shader.spv

Almost every shader tool in the Rust ecosystem sits on top of naga.

Tint (C++, Google Dawn)

Tint is the C++ compiler Google built for Dawn (Chrome's WebGPU implementation).

Tint lives inside Dawn rather than as a standalone CLI, so it usually runs from within the Chromium tree. It is close to the reference implementation of the WGSL spec.

Which compiler runs where?

EnvironmentCompiler
Chrome (any OS)Tint
Safari (Mac / iOS / visionOS)WebKit's in-house compiler (WGSL → AIR / MSL)
Firefox (any OS)naga
wgpu nativenaga
Dawn native (C++ apps)Tint

The same WGSL code passes through three different compilers and translates to three different OS graphics APIs. That is why spec conformance matters more than ever.

WGSL validation

naga --validate shader.wgsl

Validating shaders at build time catches breakage before runtime. Wiring this into CI is becoming a popular pattern.


7. Three.js WebGPU Renderer (r163+, May 2024)

r163 — Three.js WebGPU graduates

The Three.js r163 release in May 2024 made the WebGPU renderer official. It had been experimental since r137 (2022), but r163 marked it production ready.

import * as THREE from 'three'
import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js'

const renderer = new WebGPURenderer({ antialias: true })
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)

const geometry = new THREE.BoxGeometry()
const material = new THREE.MeshStandardMaterial({ color: 0x6699ff })
const cube = new THREE.Mesh(geometry, material)
scene.add(cube)

scene.add(new THREE.AmbientLight(0xffffff, 0.5))
scene.add(new THREE.DirectionalLight(0xffffff, 1))

camera.position.z = 5

renderer.setAnimationLoop(() => {
  cube.rotation.x += 0.01
  cube.rotation.y += 0.01
  renderer.render(scene, camera)
})

The code is almost identical to the WebGL renderer.

TSL — Three.js Shading Language

A more interesting Three.js bet is TSL (Three Shading Language). Instead of writing WGSL or GLSL directly, you compose shaders from JavaScript functions.

import { color, uniform, mul, sin, time, attribute } from 'three/tsl'

const baseColor = uniform(color(0xff6633))
const wave = sin(mul(attribute('position').x, 2.0).add(time))
const finalColor = baseColor.mul(wave.add(1.0).mul(0.5))

material.colorNode = finalColor

TSL emits both WGSL and GLSL automatically. One shader source targets both WebGPU and WebGL — that is the point.

Three.js migration playbook

  1. Swap the import from WebGLRenderer to WebGPURenderer
  2. Confirm it works, then gradually migrate hand-written shader bits to TSL
  3. Build out compute shaders (particles, GPGPU) as net-new features

Who uses it?


8. Babylon.js WebGPU (5.x, 6.x)

Babylon.js's bet on WebGPU

Microsoft-backed Babylon.js placed an early bet on WebGPU. The 5.0 release in 2021 introduced an experimental WebGPU engine, and 6.0 in 2023 stabilised it. Its strength is going hand-in-hand with full game-engine features.

import { Engine, WebGPUEngine, Scene, FreeCamera, Vector3, HemisphericLight, MeshBuilder } from '@babylonjs/core'

const canvas = document.getElementById('renderCanvas')
const engine = await WebGPUEngine.IsSupportedAsync
  ? await new WebGPUEngine(canvas).initAsync().then((e) => e ?? null) || new Engine(canvas, true)
  : new Engine(canvas, true)

const scene = new Scene(engine)
const camera = new FreeCamera('cam', new Vector3(0, 5, -10), scene)
camera.setTarget(Vector3.Zero())
camera.attachControl(canvas, true)

new HemisphericLight('light', new Vector3(0, 1, 0), scene)
const box = MeshBuilder.CreateBox('box', { size: 2 }, scene)

engine.runRenderLoop(() => scene.render())

WebGPUEngine.IsSupportedAsync detects support before falling back.

Babylon.js strengths

It is strong for games, simulations and digital twins. If Three.js is a "graphics building block", Babylon.js is closer to an "engine".

Babylon.js + WebGPU compute

import { ComputeShader, StorageBuffer } from '@babylonjs/core'

const cs = new ComputeShader('add', engine, {
  computeSource: `
    @group(0) @binding(0) var<storage, read_write> data: array<f32>;
    @compute @workgroup_size(64)
    fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
      data[gid.x] = data[gid.x] * 2.0;
    }
  `,
})

const buffer = new StorageBuffer(engine, 1024 * 4)
cs.setStorageBuffer('data', buffer)
cs.dispatch(16, 1, 1)

You can run GPGPU compute inline with the game engine.


9. Filament Web / regl / gpu.js / PlayCanvas

Filament Web — Google's PBR engine

Google's Filament (C++) has set the bar for mobile PBR since Android's sceneform days. It ships a WebAssembly + WebGPU/WebGL build as Filament Web.

The WebGPU backend has been ramping up through 2025. It brings the seriousness of a C++ graphics engine straight into the browser.

regl — functional WebGL / WebGPU

regl (by Mikola Lysenko) wraps imperative WebGL in a functional API. Small, fast and easy to learn.

import regl from 'regl'

const draw = regl({
  vert: `
    precision mediump float;
    attribute vec2 position;
    void main() {
      gl_Position = vec4(position, 0, 1);
    }
  `,
  frag: `
    precision mediump float;
    uniform vec4 color;
    void main() { gl_FragColor = color; }
  `,
  attributes: { position: [[-1, 0], [0, -1], [1, 1]] },
  uniforms: { color: [1, 0, 0, 1] },
  count: 3,
})

regl.frame(() => draw())

WebGPU backends (regl-gpu, etc.) are emerging. It is a popular pick for learning graphics and for data visualisation.

gpu.js — JavaScript to GPU compute

gpu.js turns JavaScript functions into GPU shaders to run as GPGPU. Historically backed by WebGL, with a WebGPU backend now landing.

import { GPU } from 'gpu.js'

const gpu = new GPU()
const multiplyMatrix = gpu
  .createKernel(function (a, b) {
    let sum = 0
    for (let i = 0; i < 512; i++) {
      sum += a[this.thread.y][i] * b[i][this.thread.x]
    }
    return sum
  })
  .setOutput([512, 512])

const c = multiplyMatrix(matA, matB)

Great for fast prototyping of ML or image processing kernels.

PlayCanvas — browser game engine

PlayCanvas is a UK-born browser game engine. ECS-based with a hosted editor, and it officially supports the WebGPU backend. It shows up a lot in 3D interactive ads and marketing experiences.

Disney and BMW are among the brands that ship 3D ads on PlayCanvas.


10. WebLLM (MLC LLM) — In-browser LLM Inference

What is WebLLM?

The CMU / MLC team's MLC LLM project built WebLLM, a library that runs LLMs (Llama, Mistral, Phi, etc.) inside the browser through WebGPU. No server, no data leaving the device.

<script type="module">
  import * as webllm from 'https://esm.run/@mlc-ai/web-llm'

  const engine = await webllm.CreateMLCEngine('Llama-3-8B-Instruct-q4f32_1-MLC')

  const reply = await engine.chat.completions.create({
    messages: [
      { role: 'system', content: 'You are a helpful assistant.' },
      { role: 'user', content: 'Tell me briefly about the future of WebGPU.' },
    ],
  })

  console.log(reply.choices[0].message.content)
</script>

The API mirrors OpenAI's chat completions (chat.completions.create).

Tech stack

Performance (2026 baseline)

About 50 to 70 percent of server inference throughput. But the zero inference cost is overwhelming.

Who uses it?


11. Transformers.js (Xenova) — WebGPU Accelerated

What is Transformers.js?

Transformers.js (authored by Xenova) ports Hugging Face's Transformers to the browser, running nearly any small model (BERT, DistilBERT, Whisper, CLIP, ViT, SAM, etc.) on-device. From 2024 onwards the WebGPU backend is official.

import { pipeline } from '@xenova/transformers'

// Force the WebGPU backend
const pipe = await pipeline('sentiment-analysis', 'Xenova/distilbert-base-uncased-finetuned-sst-2-english', {
  device: 'webgpu',
})

const result = await pipe('I love WebGPU in 2026.')
console.log(result)
// [{ label: 'POSITIVE', score: 0.9998 }]

Supported tasks

Almost every smaller Hugging Face model converts to ONNX and runs through WebGPU.

Use cases

Performance

Large models (70B class) are still out of reach, but small models (under 500M) fly. DistilBERT-base inference runs in 5 to 10 ms on a desktop WebGPU device.


12. React Three Fiber WebGPU / ONNX Runtime WebGPU

React Three Fiber (R3F) WebGPU

React Three Fiber wraps Three.js in React components. From 2025 it officially supports the WebGPU renderer.

import { Canvas } from '@react-three/fiber'
import { WebGPURenderer } from 'three/addons/renderers/webgpu/WebGPURenderer.js'

export default function Scene() {
  return (
    <Canvas
      gl={(canvas) => {
        const renderer = new WebGPURenderer({ canvas, antialias: true })
        return renderer
      }}
    >
      <ambientLight intensity={0.5} />
      <directionalLight position={[5, 5, 5]} />
      <mesh>
        <boxGeometry args={[1, 1, 1]} />
        <meshStandardMaterial color="#6699ff" />
      </mesh>
    </Canvas>
  )
}

A declarative React API on top of WebGPU acceleration. Ideal for 3D interactives in marketing and product pages.

ONNX Runtime Web — WebGPU backend

Microsoft's ONNX Runtime Web runs ONNX models in the browser. You can pick a backend among WebGL, WASM and WebGPU.

import * as ort from 'onnxruntime-web/webgpu'

const session = await ort.InferenceSession.create('./model.onnx', {
  executionProviders: ['webgpu'],
})

const feeds = { input: new ort.Tensor('float32', new Float32Array(224 * 224 * 3), [1, 3, 224, 224]) }
const results = await session.run(feeds)
console.log(results.output.data)

Models trained in PyTorch or TensorFlow get exported to ONNX and inferred in the browser through WebGPU. For enterprise workloads it is the safest default.

Which library for which scenario?

ScenarioLibrary
LLM chat demoWebLLM
Small BERT / Whisper modelsTransformers.js
Internal ONNX modelsONNX Runtime Web (WebGPU)
3D marketingThree.js / R3F WebGPU
Games / simulationsBabylon.js / PlayCanvas
Rust native + browserwgpu

13. Web Stable Diffusion — SD in the Browser

Web Stable Diffusion

The CMU / MLC team also produced Web Stable Diffusion, which runs Stable Diffusion 1.5 / 2.1 inside the browser through WebGPU. Text-to-image with no server calls.

How it works

  1. Compile UNet / VAE / text encoder via ONNX or MLC
  2. Cache the weights in IndexedDB
  3. Run the diffusion loop: text to CLIP to UNet to VAE decode
  4. Draw the final image to a canvas

The entire pipeline stays in the browser. Server bills disappear.

Applications

Limits

Solving these is the agenda for the next round of WebGPU extensions (bfloat16, mesh shaders, ray-tracing) in 2026 and 2027.


14. Compute Shaders + Storage Texture + Subgroups + the mesh shaders future

What compute shaders changed

WebGPU's real revolution is not graphics, it is GPGPU.

Toss's data visualisation team is the case study most often cited in Korea. Interactive charts with hundreds of thousands of points running at 60 fps.

Storage textures

@group(0) @binding(0) var<storage, read_write> output: texture_storage_2d<rgba8unorm, write>;

@compute @workgroup_size(8, 8)
fn cs_main(@builtin(global_invocation_id) gid: vec3<u32>) {
  let coord = vec2<i32>(i32(gid.x), i32(gid.y));
  let color = vec4<f32>(0.5, 0.7, 1.0, 1.0);
  textureStore(output, coord, color);
}

Read-only and write-only storage textures today. Read-write storage textures are slated to land later in 2026 as an extension.

Subgroups (warp messaging)

enable subgroups;

@compute @workgroup_size(64)
fn cs_main(@builtin(subgroup_invocation_id) sid: u32) {
  let value = some_input[sid];
  let sum = subgroupAdd(value);
  // 32 to 64 times faster reductions inside a warp
}

The web analogue of CUDA warp shuffle and Metal SIMD-group messaging. The key to optimising sort, scan, matmul and attention.

Mesh shaders

Instead of the classic "vertex buffer to index buffer to vertex shader to rasteriser" pipeline, mesh shaders emit small meshes (meshlets) directly. They open the door to Unreal Engine Nanite-style virtualised micropolygons.

W3C proposal stage in 2026. Stabilisation expected around 2027 to 2028.

Ray-tracing

A browser abstraction over DXR / Vulkan RT / Metal RT. Global illumination, reflections and refractions straight from a shader. Still in the proposal phase, but a huge unlock for games and visualisation once it ships.


15. Korea / Japan — Toss, Kakao Games, pixiv, CyberAgent

Korea

Toss

Since 2024 the Toss data visualisation team has been using WebGPU compute shaders. Interactive charts over hundreds of thousands of transactions and clustering algorithms now run on the GPU inside the browser. A talk at the SLASH conference sparked broader interest across the Korean developer community.

Kakao Games

Experimenting with PlayCanvas + WebGPU for some web game prototypes. Mobile browser compatibility (iOS Safari 18, Android Chrome) lowers the bar for game distribution.

NAVER LABS and D2 keep publishing WebGPU content. The CLOVA team has shipped ML inference demos based on Transformers.js and ONNX Runtime Web.

Japan

pixiv

The pixiv creator platform is rolling out WebGPU in selected interactive components (stickers and effects). Real-time effects that JavaScript could not handle now run on WebGPU compute.

CyberAgent

Heavy adoption in ads and games. 3D ads, simulations, live-broadcast effects — all migrating to WebGPU. Some of AbemaTV's interactive content is part of this wave.

LINE / Yahoo Japan

Piloting WebGPU compute shaders for large-scale data visualisation. The motivation is similar to Toss.

Globally


16. Who Should Learn WebGPU? Games / Data Viz / Browser ML

Recommendations by scenario

Games and interactive 3D

Data visualisation (hundreds of thousands to millions of points)

Browser ML inference

Native + web integration

Learning path

  1. WGSL basics — start with small @vertex, @fragment, @compute programs
  2. Calling WebGPU directly — touch pipelines, bind groups and buffers by hand
  3. Three.js / Babylon.js — fast wins with high-level libraries
  4. Compute shaders — GPGPU patterns (reduce, scan, matmul)
  5. ML inference integration — apply Transformers.js or ONNX Runtime Web

Common pitfalls

Conclusion — the GPU web of 2026

WebGPU is no longer "coming soon". It is already here. Chrome, Safari and Firefox are all GA. The spec is at CR. The library ecosystem is mature. The 2026 answer is simple.

For new graphics or GPGPU projects, start with WebGPU and keep WebGL as a safety net. Browser ML at any scale is no longer feasible without WebGPU.


References

Comments

No comments yet.

Sign in to leave a comment