npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

wgpu-bun

v29.1.0

Published

WebGPU for Bun. A bun:ffi binding to wgpu-native, API-compatible with the `webgpu` package — headless compute and offscreen rendering, no canvas required.

Readme

wgpu-bun

npm ci licence bun

The webgpu npm package segfaults Bun. This is a WebGPU that runs there. A bun:ffi binding to both major implementations — wgpu, the core of WebGPU in Firefox, Servo and Deno, and Chromium's Dawn — selectable at runtime, API-compatible with webgpu. Headless compute, offscreen rendering and shader validation on Windows x64, Linux x64/arm64 and macOS arm64.

bun add wgpu-bun
import { create, globals } from 'wgpu-bun';

Object.assign(globalThis, globals);            // GPUBufferUsage, GPUShaderStage, …

const gpu = create([]);
const adapter = await gpu.requestAdapter();
const device = await adapter!.requestDevice();

device.pushErrorScope('validation');
const module = device.createShaderModule({ code: '/* wgsl */' });
const error = await device.popErrorScope();    // ← reports, with negative tests proving it can
if (error) throw new Error(error.message);

The native library and the ABI shim arrive with it as an optionalDependencies platform package matching your os/cpu. No install hook, no toolchain, no cargo.

It renders

That is examples/sky.ts, a WGSL port of RedPewEngine's Hillaire atmosphere: two compute kernels build the transmittance and multiple-scattering tables, a third ray-marches the sky into a 192×108 image, a fullscreen shader adds an analytic sun disc and exposes it.

bun run examples/sky.ts   # → sky.png

| | | |:-:|:-:| | | | | pathtracer — 900×900, 4 096 spp × 8 bounces, 3.3 billion primary rays, one dispatch | lorenz — 65 536 trajectories × 3 000 RK4 steps, up to 196 M atomicAdds, no render pass | | | | | mandelbrot — 5 556× zoom, smoothed escape time, 4× supersampled | reaction-diffusion — 4 000 ping-ponged dispatches in one command buffer |

Plus triangle.ts, the shortest thing that proves an install works. Gallery: examples/README.md.

Batteries: wgpu-bun/image

import { saveTexturePng, readTexture, encodePng } from 'wgpu-bun/image';

await saveTexturePng(device, target, 'frame.png');

copyTextureToBuffer demands a 256-byte-aligned row stride, so the buffer that comes back is almost never the image: a 1400-pixel-wide RGBA frame arrives with 5 600 bytes of pixels and 32 bytes of padding per row, and code that ignores it renders a picture that shears. readTexture hands back tightly packed rows, and refuses a texture without COPY_SRC up front because letting that reach wgpuQueueSubmit aborts the process. encodePng has no dependencies. All of it is a subpath, so create, globals and isMac stay the whole compatibility surface.

Which one should you use

| | wgpu-bun | bun-webgpu | webgpu | |---|---|---|---| | Backend | wgpu-native — the Rust wgpu behind Firefox, Servo and Deno | Dawn — Chromium's | Dawn — Chromium's | | Runs under Bun | yes | yes | no — the N-API addon segfaults the runtime | | popErrorScope() | reports, with negative tests proving it can go red | crashes its allocator, even on an empty scope | works | | getCompilationInfo() | real diagnostics, synthesised from the validation error | unimplemented | works | | Surfaces / windowing | no — headless and offscreen only | no | no |

bun-webgpu covers the heavy end of the API competently and is a reasonable answer if Dawn is what you want. Full assessment: docs/ERROR-PATH.md.

Dawn, if you want it

The default is wgpu-native; WGPU_BUN_IMPL=dawn selects Dawn at runtime, from a separate opt-in platform package — name-reserved today, so build it from a checkout until the first Dawn release. The 92 aggregates this binding lays out are field-identical in both headers, so nothing above the loading layer changes, and the whole suite runs green against either, on all three platforms in public CI, over Vulkan, D3D12 and Metal. Google ships static archives only, so this repository links its own, with the ABI shim fused in, from a tag and a sha256. What differs: docs/DAWN.md.

Status

Green on every supported platform, against three graphics APIs, on wgpu-native v29.0.1.1:

| platform | adapter | API | |---|---|---| | win32-x64 | Microsoft Basic Render Driver (WARP), and a discrete NVIDIA adapter locally | D3D12 | | linux-x64 | llvmpipe (Mesa lavapipe) | Vulkan | | linux-arm64 | llvmpipe (Mesa lavapipe) | Vulkan | | darwin-arm64 | Apple Paravirtual device | Metal |

Three calling conventions. CI legs that cannot reach a device fail rather than skip, so a green matrix means the suite ran, not that it was excused.

Implemented: adapter, device, buffers, textures, samplers, bind groups, pipelines, encoders, queues; WGSL compilation, compute dispatch, render to texture, buffer readback, error scopes, getCompilationInfo(), backend selection.

Refused, not stubbed. A call either does the thing or throws saying it does not exist, including the 40 wgpu-native symbols that abort the process, which are blocklisted by name. Out of scope: surfaces, render bundles, indirect draw, occlusion queries, external textures (why). Not done yet: no WebGPU CTS run, and no discrete GPU outside Windows (the full list).

Versioning: the major is the wgpu-native generation

[email protected] binds wgpu-native v29. That digit is not a maturity signal; it names the native library inside, which decides ABI, validation strictness and WGSL acceptance. When upstream moves to v30, so does this major; minor and patch are ordinary semver. A test asserts the major is WGPU_NATIVE_MAJOR, so a pin bump cannot ship as 29.x and tell everyone the ABI did not move.

It ships v29 and accepts v27. If your Rust half is on wgpu 27, point WGPU_NATIVE_LIB at that library, or run bun run fetch --generation 27; the same suite that certifies v29 runs against it on every platform in CI. An untested generation is refused at load rather than warned about, because the differences between generations produce wrong answers rather than errors. Measurements: docs/GENERATIONS.md.

Where the binaries come from

wgpu-native is pinned by URL and sha256 and fetched at release time: nothing committed, nothing downloaded at install. Two upstreams are watched on different terms — wgpu-native by version, Dawn by the calendar — and .github/workflows/upstream-watch.yml files an issue when one is due. Details: docs/PACKAGING.md.

Migrating from webgpu

An import-specifier change and nothing else: the same three exports (create, globals, isMac) over standard @webgpu/types. Route it through a one-line local re-export module and swapping back is a single edit for a whole codebase. The differences — the two Dawn-proprietary globals, navigator.gpu, copyExternalImageToTexture — are in docs/COMPATIBILITY.md.

Confirming an install landed:

import { resolveNativeLibrary, STATUS } from 'wgpu-bun';

console.log(STATUS);
console.log(resolveNativeLibrary());
// { path: '…/vendor/win32-x64/lib/wgpu_native.dll', source: 'vendor',
//   includeDir: '…/vendor/win32-x64/include', version: 'v29.0.1.1' }

Documentation

Working on the package

bun install
bun run fetch          # download + verify the pinned wgpu-native for this host
bun run shim:build     # build the ABI shim (needs cargo; see docs/ABI.md)
bun run check:layouts  # confirm the generated struct layouts match those headers
bun run typecheck
bun test
bun run test:matrix    # the suite × every implementation and backend this host can reach

The backend is a correctness knob — the same GPU exposes shader-f16 over Vulkan and not over D3D12 — and CI cannot sweep it: every runner has exactly one usable backend. test:matrix does. shim:build is optional only on win32-x64, where the direct path is correct anyway, and worth building even there since it is the path that ships everywhere else. On the other three RIDs it is not optional: without it the GPU suites skip with abi-unsupported.

Licence

MIT © 2026 Argon Inc — see LICENSE, covering this repository's own code only.

wgpu-native is dual-licensed MIT or Apache-2.0 by the gfx-rs project. Its binaries are fetched from upstream's own releases rather than vendored here, but the per-platform npm packages do redistribute them, so those declare MIT OR Apache-2.0 and carry LICENSE-WGPU-NATIVE (why). bun-webgpu (Apache-2.0) is credited as prior art; not a dependency, and no code is taken from it.