# wgpu: a safe Rust graphics API built around the WebGPU standard

> The library behind the WebGPU implementations in Firefox, Servo and Deno, sitting on a Hal and Naga stack that translates your shaders and talks to Vulkan, Metal, D3D12 and OpenGL.

**gfx-rs/wgpu** — A cross-platform, safe, pure-Rust graphics API.

- Repository: https://github.com/gfx-rs/wgpu
- Website: https://wgpu.rs
- Stars: 18,254 · Forks: 1,511
- Language: Rust
- License: Apache-2.0
- Published: 2026-10-06 · Updated: 2026-10-06 · Language: en
- Canonical page: https://hysenlabs.com/projects/gfx-rs-wgpu

## One safe Rust API over Vulkan, Metal, D3D12 and OpenGL

The README's first substantive sentence defines the scope: `wgpu` is a cross-platform, safe, pure-Rust graphics API. It runs natively on Vulkan, Metal, D3D12 and OpenGL, and on top of WebGL2 and WebGPU when compiled to wasm. That list is the real product, because the hard part of portable graphics is not the API you call, it is the four completely different native interfaces underneath it.

The repository tree shows how the layering works. The crate you depend on is `wgpu/`. Underneath sit `wgpu-hal/`, which is the hardware abstraction layer that knows how to talk to each backend, and `wgpu-core/`, which owns device, queue and pipeline state. `wgpu-types/` holds the types shared across those boundaries, and `wgpu-core-remote/` plus `wgpu-core-remote-types/` handle serialising that state across a process boundary. `naga/` is the shader translator, with `naga-types/` for its shared definitions and `naga-cli/` for running it standalone.

So the shape is: your code, then Naga turning WGSL or SPIR-V or HLSL or MSL into something the backend understands, then Hal issuing the native calls. The 1,251 open issues on the repository are consistent with a project of that shape, where most of the work is not designing an API but making four backends agree on the details.

## WebGPU is the design target, not a compatibility layer bolted on

The API is based on the WebGPU standard, and the README is direct about the consequence: it is a fully native Rust library, not a browser binding. The second sentence of the README is the one that settles the project's importance: `wgpu` serves as the core of the WebGPU integration in Firefox, Servo and Deno.

That placement has real architectural consequences for you as a user. When a browser ships, it ships against this library, so anything that would make the browser slow or unsafe tends not to make it into the API in the first place. When a spec ambiguity turns up, wgpu is often where it gets resolved, and the resolution then propagates outward. A design decision in wgpu is closer to a WebGPU decision than to a Rust library decision.

It also means the API is not shaped by what native graphics APIs historically offered. There is no fixed-function pipeline sitting next to a programmable one, because there were no direct consumers who needed the fixed-function path in a browser. If you are porting from OpenGL or Direct3D, the mental adjustment is usually bigger than the Rust adjustment.

The README points beginners at two external tutorials rather than trying to teach inline: Learn Wgpu at sotrh.github.io for the Rust library, and WebGPU Fundamentals for the specification side, noting it is very similar minus the differences between Rust and JavaScript. The `cts_runner/` directory in the tree is the WebGPU conformance test suite, which is the clearest available signal that the implementation is checked against the standard rather than against its own tests.

## Running an example and forcing a specific adapter

The README's getting-started instruction is one command, which runs any of the examples in the `examples/` directory:

```bash
cargo run --bin wgpu-examples <example>
```

The examples live at wgpu.rs/examples when you read them in a browser, and the tree groups them into `examples/features/`, `examples/standalone/` and `examples/bug-repro/`. The `bug-repro` group is a detail worth pausing on. A project that keeps minimal reproductions in its own tree as first-class examples is telling you it expects platform-specific bugs and wants them reported in a runnable form.

More interesting than the examples are the environment variables, because they are how you debug a graphics problem without recompiling. `WGPU_BACKEND` takes a comma-separated list of the backends you want, from `vulkan`, `metal`, `dx12` and `gl`. `WGPU_ADAPTER_NAME` takes a case-insensitive substring, so `1080` matches an `NVIDIA GeForce 1080ti` as the README puts it. `WGPU_DX12_COMPILER` selects `dxc`, `static-dxc` or `fxc`, with the note that `dxc` needs `dxcompiler.dll` at version 1.8.2502 or newer in the working directory.

These are used by testing, examples and the `::from_env()` methods, which means they are a supported interface rather than a debug leftover. The README notes a separate family for the conformance runner: `DENO_WEBGPU_ADAPTER_NAME`, `DENO_WEBGPU_BACKEND`, `DENO_WEBGPU_POWER_PREFERENCE`, `DENO_WEBGPU_DX12_COMPILER` and `DENO_WEBGPU_STRICT_COMPLIANCE`.

The workspace metadata is worth a glance too, since it tells you what the crates are packaged as:

```toml
edition = "2021"
rust-version = "1.95"
keywords = ["graphics"]
license = "MIT OR Apache-2.0"```
```

That last line is the licensing answer: dual MIT or Apache-2.0, the same pair used across much of the Rust ecosystem, and recorded in `LICENSE.APACHE` and `LICENSE.MIT` at the repository root.

## What the platform support table does and does not promise

The README carries a support matrix with three tiers, and the tiers are where the honest detail lives. First class support means the backend is the expected path. Downlevel, best effort means it works but is not the primary target. A third marker means it requires the ANGLE translation layer and works only with GL ES 3.0.

Read carefully, the table is narrower than the first sentence suggests. Vulkan is first class on Windows and on Linux and Android. Metal is first class on macOS and iOS. DX12 is first class on Windows only. OpenGL is downlevel everywhere it appears: GL 3.3+ or the ANGLE path on Windows, GL ES 3.0+ on Linux and Android, and WebGL2 on the web.

Two translation layers appear as first-class dependencies rather than fallbacks. Vulkan on macOS and iOS is marked as requiring MoltenVK, LunarG's Vulkan-on-Metal layer. The ANGLE marker means GL ES 3.0 only, and the README is specific about how to enable it: on macOS and iOS use the `angle` feature, and on Windows `gles` uses WGL by default, so you build with `cfg(windows_angle)` to use ANGLE instead. That is the kind of detail that decides whether a project works on your target hardware, and it is in the README rather than hidden in a wiki.

So the accurate summary is: pick the primary native API for your platform. Windows has two first-class choices, Apple platforms have Metal, Linux and Android have Vulkan, and OpenGL is the compatibility path with caveats attached to each of them.

## A breaking release every three months, and what v30 actually changed

The README states the cadence plainly: a breaking version is released every three months, and the MSRV can only be upgraded in breaking releases. Version 30 is the current line, with 30.0.0 published on 2026-07-01 and a 30.0.1 patch on 2026-08-22.

Version 30 is a good illustration of what a wgpu breaking change looks like, because both headline changes are small in surface area and unavoidable in practice. The first makes vertex buffer slots optional, so `VertexState`'s `buffers` field changes to a slice of `Option<VertexBufferLayout>` and existing layouts must be wrapped in `Some`. The second removes a default: Naga no longer assumes integer-typed shader I/O should be `flat`, so `@interpolate(flat)` that used to be implied on an integer varyings field now has to be written out. Neither is a redesign. Both exist because the WebGPU specification requires them.

The patch releases are a better guide to real-world cost. 30.0.1 fixes a Vulkan bug where an un-waited fence was passed to `vkAcquireNextImageKHR` on non-Windows platforms, which produced a validation error every single frame since 30.0.0 shipped. It also resolves Metal colour space constants dynamically, and upgrades the vendored WebGPU bindings to fix a panic when `requestAdapter()` fails on the wasm backend. The 29.0.4 patch restored `Queue::as_raw` after it had been removed without good reason in v29, and fixed a Vulkan memory-model validation error caused by the SPIR-V backend emitting storage atomics with device scope.

Read that list as a cost estimate rather than as reassurance. A project with this many backends will ship regressions in any release, and some of them, like the per-frame Vulkan validation error, are the kind that show up as a performance problem long before anyone reads the validation output.

## The MSRV is tied to two browsers you did not choose

The minimum supported Rust version policy is unusual enough to be worth reading closely, because it tells you who actually constrains the project. There are three numbers. The `wgpu` MSRV is 1.87, and `wgpu-core`, and therefore `wgpu-hal`, `naga`, `naga-types` and `wgpu-types`, is also 1.87. Everything else in the workspace is 1.95.

The reasoning underneath is spelled out in the README. The `wgpu-core` crate should never require an MSRV ahead of Firefox's MSRV for nightly builds, determined by `MINIMUM_RUST_VERSION` in Firefox's mozboot. The `wgpu` crate should never require an MSRV ahead of Servo's MSRV, read from their rust-version declaration in `Cargo.toml`. Those two rules exist so that shipping a wgpu-based browser build is never blocked by a Rust upgrade.

This is good engineering and a real constraint. If you build Firefox or Servo or Deno, the 1.87 number is a hard ceiling you do not control. If you are writing an application, the 1.87 floor applies to the library and you can use a newer toolchain for your own code.

The policy is enforced on CI in `.github/workflows/ci.yml` using the `WGPU_MSRV`, `CORE_MSRV` and `REPO_MSRV` variables, so the three numbers are checked rather than aspirational. Everything else in the tree supports the same picture of how the project is run: `rust-toolchain.toml` pinning the toolchain, `rustfmt.toml` and `clippy.toml` and `typos.toml` for linting, `renovate.json` for dependency updates, `GOVERNANCE.md` and `CODE_OF_CONDUCT.md` for how decisions get made, `benches/` and `lock-analyzer/` for performance work, and `player/` alongside `naga-test/` for shader validation. The `AGENTS.md` and `CLAUDE.md` at the root, plus a `.agents/` directory, show the same tooling-awareness seen elsewhere in the Rust graphics ecosystem.

For a C or C++ caller the README points to `wgpu-native`, the C bindings, and to Learn WebGPU for C++. For everything else, `wgpu.rs` is the documentation entry point and docs.rs carries the versioned modules the README refers to as its documentation guides.

## Conclusion

wgpu is the right choice when you want one shader and one pipeline description to run on a browser, a Linux workstation, a Mac and a Windows box, and you are willing to accept a breaking release roughly every three months. The Hal layer is what makes that work, and the price is that GPU-specific features exist only where all backends can express them. Two things to check before committing: whether your target platforms are first class in the support table or depend on MoltenVK or ANGLE, and whether your Rust toolchain is new enough, since the MSRV is 1.87 for the library and 1.95 for the rest of the workspace. Start with the examples directory and the documentation modules rather than the README, which is short by design.

## FAQ

### What is the difference between WebGPU and wgpu?

WebGPU is the browser API standard, defined at gpuweb.github.io/gpuweb. wgpu is a Rust library whose API is based on that standard but is fully native, with no browser required. wgpu is the core of the WebGPU integration in Firefox, Servo and Deno, so the two track each other closely without being the same thing.

### What does WGPU mean?

It is the project's name, the repository `gfx-rs/wgpu`, standing for WebGPU. The library takes that name because its API is modelled on the WebGPU standard, and it runs natively on Vulkan, Metal, D3D12 and OpenGL rather than only in a browser. For C and C++ callers, the separate `wgpu-native` project provides C bindings to the same library.

### What is WebGPU used for?

It is a modern graphics and compute API for the web, replacing WebGL. Because wgpu mirrors that standard in Rust, the same shader and pipeline code can target a browser or a native Vulkan, Metal, D3D12 or OpenGL backend. That portability is the reason the specification and the library developed together.

### Is WebGPU written in Rust?

The specification itself is not tied to any language, and implementations exist in several. wgpu, the reference-quality Rust implementation the README describes as serving as the core of the WebGPU integration in Firefox, Servo and Deno, is written in Rust, and `wgpu-native` exposes it to C and C++ as a set of C bindings.

## Sources

- [gfx-rs/wgpu on GitHub](https://github.com/gfx-rs/wgpu)
- [License: Apache-2.0](https://github.com/gfx-rs/wgpu/blob/trunk/LICENSE)
- [Project website](https://wgpu.rs)
- [README](https://github.com/gfx-rs/wgpu/blob/trunk/README.md)
- [Releases](https://github.com/gfx-rs/wgpu/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/gfx-rs-wgpu
