Package Exports
- @sylphx/webgpu
- @sylphx/webgpu/webgpu.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@sylphx/webgpu) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@sylphx/webgpu
Production-ready WebGPU for Node.js & Bun - 100% standard-compliant, built with Rust + wgpu
โจ What is @sylphx/webgpu?
The modern, lightweight WebGPU implementation for Node.js. Use the same WebGPU API in both Node.js and browsers - write once, run everywhere.
const { Gpu, GPUBufferUsage } = require('@sylphx/webgpu')
// Initialize GPU (identical to browser API)
const gpu = Gpu()
const adapter = await gpu.requestAdapter()
const device = await adapter.requestDevice()
// Create buffer (100% WebGPU standard)
const buffer = device.createBuffer({
size: 256,
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
})
// Run compute shader
const encoder = device.createCommandEncoder()
const pass = encoder.beginComputePass()
pass.setPipeline(pipeline)
pass.setBindGroup(0, bindGroup)
pass.dispatchWorkgroups(64)
pass.end()
device.queue.submit([encoder.finish()])๐ Why Choose @sylphx/webgpu?
| Feature | @sylphx/webgpu | @kmamal/gpu (Dawn) |
|---|---|---|
| WebGPU Standard | โ 100% compliant | โ ๏ธ Custom API |
| Binary Size | 1.9-4.6MB | 50-150MB |
| Build Time | ~30 seconds | 1-3 hours |
| Code Portability | โ Browser compatible | โ Node.js only |
| Implementation | Firefox's wgpu (Rust) | Chrome's Dawn (C++) |
| Toolchain | Simple (Cargo) | Complex (depot_tools) |
| Status | v1.0 - Production ready | 0.x - Pre-release |
Key Advantages
โ 100% WebGPU Standard - Share code between Node.js and browsers โ Production Ready - v1.0.1 stable release with 58 tests, 100% pass rate โ Ultra Lightweight - 2-5MB binaries vs 100MB+ alternatives โ Modern Stack - Rust + wgpu (used by Firefox, Deno, Bevy) โ Cross-Platform - 6 prebuilt platforms (macOS, Linux, Windows, ARM64) โ Well Tested - Comprehensive test suite covering all features
๐ฆ Installation
npm install @sylphx/webgpuRequirements:
- Node.js 18+ or Bun 1.0+
- No build tools needed (prebuilt binaries included)
Supported Platforms:
- macOS (x64, ARM64/M1/M2/M3)
- Linux (x64, ARM64)
- Windows (x64, ARM64)
- FreeBSD, Android (via source build)
๐ฏ Quick Start
Basic GPU Setup
const { Gpu } = require('@sylphx/webgpu')
async function main() {
// Create GPU instance
const gpu = Gpu()
// Request adapter (automatically selects best GPU)
const adapter = await gpu.requestAdapter({
powerPreference: 'high-performance'
})
console.log('GPU:', adapter.info.name)
console.log('Backend:', adapter.info.backend)
// Request device
const device = await adapter.requestDevice()
console.log('โ
WebGPU ready!')
}
main()Compute Shader Example
const { Gpu, GPUBufferUsage } = require('@sylphx/webgpu')
async function runCompute() {
const gpu = Gpu()
const adapter = await gpu.requestAdapter()
const device = await adapter.requestDevice()
// Create buffers
const size = 256
const input = device.createBuffer({
size,
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
})
const output = device.createBuffer({
size,
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
})
// Create compute shader (WGSL)
const shader = 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>) {
output[id.x] = input[id.x] * 2.0;
}
`
})
// Create bind group layout
const layout = device.createBindGroupLayout({
entries: [
{ binding: 0, visibility: 4, buffer: { type: 'read-only-storage' } },
{ binding: 1, visibility: 4, buffer: { type: 'storage' } }
]
})
// Create bind group
const bindGroup = device.createBindGroup({
layout,
entries: [
{ binding: 0, resource: { buffer: input } },
{ binding: 1, resource: { buffer: output } }
]
})
// Create pipeline
const pipeline = device.createComputePipeline({
layout: device.createPipelineLayout({ bindGroupLayouts: [layout] }),
compute: { module: shader, entryPoint: 'main' }
})
// Execute compute shader
const encoder = device.createCommandEncoder()
const pass = encoder.beginComputePass()
pass.setPipeline(pipeline)
pass.setBindGroup(0, bindGroup)
pass.dispatchWorkgroups(4) // 4 * 64 = 256 threads
pass.end()
device.queue.submit([encoder.finish()])
console.log('โ
Compute shader executed!')
}
runCompute()Render Pipeline Example
const { Gpu, GPUBufferUsage, GPUTextureUsage } = require('@sylphx/webgpu')
async function renderTriangle() {
const gpu = Gpu()
const adapter = await gpu.requestAdapter()
const device = await adapter.requestDevice()
// Create vertex buffer
const vertices = new Float32Array([
// x, y, r, g, b
0.0, 0.5, 1.0, 0.0, 0.0, // top (red)
-0.5, -0.5, 0.0, 1.0, 0.0, // bottom left (green)
0.5, -0.5, 0.0, 0.0, 1.0 // bottom right (blue)
])
const vertexBuffer = device.createBuffer({
size: vertices.byteLength,
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
mappedAtCreation: true
})
new Float32Array(vertexBuffer.getMappedRange()).set(vertices)
vertexBuffer.unmap()
// Create shader
const shader = device.createShaderModule({
code: `
struct VertexInput {
@location(0) position: vec2f,
@location(1) color: vec3f
}
struct VertexOutput {
@builtin(position) position: vec4f,
@location(0) color: vec3f
}
@vertex
fn vs_main(in: VertexInput) -> VertexOutput {
var out: VertexOutput;
out.position = vec4f(in.position, 0.0, 1.0);
out.color = in.color;
return out;
}
@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4f {
return vec4f(in.color, 1.0);
}
`
})
// Create render pipeline
const pipeline = device.createRenderPipeline({
layout: 'auto',
vertex: {
module: shader,
entryPoint: 'vs_main',
buffers: [{
arrayStride: 20,
attributes: [
{ shaderLocation: 0, offset: 0, format: 'float32x2' },
{ shaderLocation: 1, offset: 8, format: 'float32x3' }
]
}]
},
fragment: {
module: shader,
entryPoint: 'fs_main',
targets: [{ format: 'rgba8unorm' }]
}
})
// Create texture for rendering
const texture = device.createTexture({
size: { width: 512, height: 512 },
format: 'rgba8unorm',
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC
})
// Render triangle
const encoder = device.createCommandEncoder()
const pass = encoder.beginRenderPass({
colorAttachments: [{
view: texture.createView(),
loadOp: 'clear',
storeOp: 'store',
clearValue: { r: 0.1, g: 0.1, b: 0.1, a: 1.0 }
}]
})
pass.setPipeline(pipeline)
pass.setVertexBuffer(0, vertexBuffer)
pass.draw(3)
pass.end()
device.queue.submit([encoder.finish()])
console.log('โ
Triangle rendered!')
}
renderTriangle()๐ Complete Examples
Check the examples/ directory for more:
- basic.js - GPU setup and adapter info
- compute.js - Vector addition compute shader
- triangle.js - Render colored triangle
- texture-upload.js - Upload and sample textures
- textured-quad.js - Render textured quad with samplers
- cube.js - 3D cube with depth testing
- transparency.js - Alpha blending
- msaa.js - Multi-sample anti-aliasing
- mrt.js - Multiple render targets (G-buffer)
- indirect-draw.js - GPU-driven rendering
- indirect-compute.js - GPU-driven compute
- render-bundle.js - Reusable render bundles
- timestamp-queries.js - GPU performance profiling
Run any example:
node examples/compute.js
# or with Bun (faster startup)
bun examples/compute.js๐ API Documentation
Full WebGPU Standard API
The API is 100% compliant with the W3C WebGPU specification. Code written for browsers works identically in Node.js.
Core Objects:
Gpu- Entry point (equivalent tonavigator.gpu)GPUAdapter- Physical GPU representationGPUDevice- Logical device for GPU operationsGPUBuffer- GPU memory bufferGPUTexture- GPU texture (images)GPUSampler- Texture sampling configurationGPUShaderModule- Compiled WGSL shaderGPUBindGroup- Resource bindingsGPUPipelineLayout- Pipeline resource layoutGPUComputePipeline- Compute shader pipelineGPURenderPipeline- Render pipelineGPUCommandEncoder- Command recordingGPUComputePassEncoder- Compute pass recordingGPURenderPassEncoder- Render pass recordingGPUQueue- Command submission queue
Constants (WebGPU Standard):
const {
GPUBufferUsage, // Buffer usage flags
GPUTextureUsage, // Texture usage flags
GPUMapMode, // Buffer map modes
GPUShaderStage // Shader stage flags
} = require('@sylphx/webgpu')Key Differences from Browser
Entry Point:
// Browser
const adapter = await navigator.gpu.requestAdapter()
// Node.js (@sylphx/webgpu)
const { Gpu } = require('@sylphx/webgpu')
const gpu = Gpu()
const adapter = await gpu.requestAdapter()Everything else is identical! All methods, properties, and descriptors match the browser API exactly.
๐ Browser Compatibility
Share code between Node.js and browsers:
// Universal WebGPU code (works in both!)
export async function initGPU() {
// Detect environment
const gpu = typeof navigator !== 'undefined'
? navigator.gpu
: require('@sylphx/webgpu').Gpu()
const adapter = await gpu.requestAdapter()
const device = await adapter.requestDevice()
// All code below is identical!
const buffer = device.createBuffer({
size: 256,
usage: GPUBufferUsage.STORAGE
})
return { device, buffer }
}๐ง Advanced Features
GPU Profiling with Timestamp Queries
const querySet = device.createQuerySet({
type: 'timestamp',
count: 2
})
const encoder = device.createCommandEncoder()
encoder.writeTimestamp(querySet, 0)
// ... GPU work ...
encoder.writeTimestamp(querySet, 1)
device.queue.submit([encoder.finish()])
// Read timing results
const timings = await readTimestamps(querySet)
console.log(`GPU time: ${(timings[1] - timings[0]) / 1e6}ms`)Indirect Draw (GPU-Driven Rendering)
// GPU generates its own draw commands
const indirectBuffer = device.createBuffer({
size: 20,
usage: GPUBufferUsage.INDIRECT | GPUBufferUsage.STORAGE
})
// Compute shader writes draw commands
// Render pass reads from buffer
pass.drawIndirect(indirectBuffer, 0)Multiple Render Targets (Deferred Rendering)
const pass = encoder.beginRenderPass({
colorAttachments: [
{ view: positionTexture.createView(), ... }, // G-buffer position
{ view: normalTexture.createView(), ... }, // G-buffer normal
{ view: albedoTexture.createView(), ... } // G-buffer albedo
]
})๐งช Testing
# Run all tests
npm test
# Watch mode
npm run test:watch
# Coverage report
npm run test:coverageTest Suite:
- 58 comprehensive tests
- 100% pass rate
- Covers all WebGPU features
- Real GPU operations (not mocked)
๐๏ธ Building from Source
# Install Rust (if not already installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Clone repository
git clone https://github.com/SylphxAI/webgpu.git
cd webgpu
# Install dependencies
npm install
# Build native bindings (~30 seconds clean build)
npm run build
# Run tests
npm test๐ Performance
Binary Size (Actual Prebuilt Binaries):
- @sylphx/webgpu: 1.9-4.6MB (macOS: 1.9-2.2MB, Linux: 3.0-3.5MB, Windows: 4.1-4.6MB)
- @kmamal/gpu: 50-150MB (Dawn binaries)
Build Time (Clean Build):
- @sylphx/webgpu: ~30 seconds (Cargo release build)
- @kmamal/gpu: 1-3 hours (Dawn + depot_tools)
Runtime Performance:
- GPU operations: Zero overhead (thin wrapper)
- CPU overhead: <10% for descriptor transformation
- Compute/Render: Limited by GPU, not bindings
๐ ๏ธ Architecture
User Code (WebGPU Standard API)
โ
webgpu.js (JavaScript wrapper - transforms descriptors)
โ
index.js (napi-rs native bindings)
โ
Rust (wgpu implementation)
โ
GPU Drivers (Metal/Vulkan/DX12)The JavaScript wrapper provides 100% standard WebGPU API while the Rust layer uses optimized flat signatures for napi-rs compatibility.
๐ค Contributing
We welcome contributions! See CONTRIBUTING.md for guidelines.
Areas for Contribution:
- ๐ Additional examples and tutorials
- ๐งช More test cases and benchmarks
- ๐ Integration with frameworks (Three.js, Babylon.js, etc.)
- ๐ Documentation improvements
- ๐ Bug reports and fixes
๐ License
MIT ยฉ SylphxAI
๐ Resources
- API Documentation - Complete API reference
- WebGPU Specification - Official W3C spec
- wgpu-rs - Underlying Rust implementation
- Examples - 13 working examples
- CHANGELOG - Version history
- ROADMAP - Project status and future plans
โญ Star History
If you find this project useful, please consider giving it a star on GitHub!
Ready to use WebGPU in Node.js?
npm install @sylphx/webgpuv1.0.1 - Production Ready ๐