This page describes how to link Lygia shader functions into your WebGPU application using WESL tools.
WESL is a superset of WGSL that adds features with community-supported tools. WESL tools are available in Rust and JavaScript/TypeScript.
Most (but not all) Lygia GLSL shaders are now available for WebGPU using WESL. If a Lygia function you need is missing, please file an issue or help contribute.12
Install with npm install lygia or pnpm install lygia
(lygia npm package).
Once you install, 500+ Lygia functions
and constants will be available for you to use
via import statements in your application shader code.
import lygia::math::consts::PI;
fn main() {
let p = PI;
}The JS tools automatically tree-shake, including only the Lygia functions your application uses.
WESL integrates with popular bundlers (vite, webpack, rollup) through plugins,
or for custom build pipelines, you can use the wesl-link command-line tool
or the link API.
If you build your application with a JavaScript/TypeScript bundler
like vite, webpack or rollup,
install the
wesl and
wesl-plugin packages.
Import shader code into your JavaScript or TypeScript application using the
import statements suffixed with ?link and the shaders will be linked together at runtime:
import appWesl from "../shaders/app.wesl?link";
import { link } from "wesl";
const linked = await link(appWesl);
linked.createShaderModule(gpuDevice);For more details, check the WESL bundler documentation or refer to this lygia example using vite.
Alternatively,
you can statically link your shaders in advance using the ?static suffix:
import appWgsl from "../shaders/app.wesl?static";See the lygia static linking example for details.
Static linking bundles your shader modules together into a single transpiled WGSL string.
Static linking means you don't need WESL linker in your runtime bundle (~15KB savings).
However, static linking is less flexible
because your application can't use WESL's conditional compilation
features (@if directives) to adapt shaders at runtime based on GPU capabilities
or user configuration.
Many Lygia shader functions include @if conditions.
For example see @if(YUV_SDTV) in yuv2rgb.
With runtime linking, you can set these conditions dynamically.
With static linking, conditions are resolved at build time.
For custom build pipelines, use the wesl-link command-line tool to statically link shaders.
Link your application shader file that imports Lygia functions:
npx wesl-link ./shaders/main.weslSee the Lygia CLI linking example for details.
To get standalone WGSL for a specific Lygia module, call wesl-link on that module.
From the npm package:
npx wesl-link lygia::color::layer::addSourceOverFrom a lygia repository clone:
npx wesl-link package::color::layer::addSourceOver
# alternate syntax
npx wesl-link color/layer/addSourceOver.weslEither approach produces the WGSL for the requested Lygia module linked with its dependencies.
You can use the linking API directly to build custom solutions:
import { link } from "wesl";
const main = `import lygia::math::consts::PI; ...`;
const linked = await link({weslSrc: {main }});
const shaderModule = linked.createShaderModule(gpuDevice);See the API documentation for details.
More WESL examples are available here.
Most examples run with one click in a browser sandbox.
The examples can also be used as starter templates with degit.
cargo add lygiacargo add --build wesl/// build.rs
fn main() {
wesl::Wesl::new("src/shaders").build_artifact("main.wesl", "my_shader");
}cargo add wesllet shader_string = Wesl::new("src/shaders")
.compile("main.wesl")
.inspect_err(|e| eprintln!("WESL error: {e}")) // pretty errors with `display()`
.unwrap()
.to_string();cargo install wesl-cli
wesl compile <path/to/shader.wesl>See Getting Started Rust, the wesl crate documentation, and WESL rust examples.
WESL extends WGSL with:
importstatements to split shader code across files and load npm/cargo libraries@if @else @elseifstatements to assemble specialized shaders at build time or runtime
Current WESL tools include:
- Linkers in Rust and JavaScript (to combine WGSL/WESL files into applications)
- Syntax highlighters for zed, helix and nvim
Additional WESL tools in development:
- HTML documentation generator
- Language server
- VSCode plugin
- Code formatter
Read more about WESL at wesl-lang.dev.
Footnotes
-
Lygia functions are small and self-contained. You can just copy, paste and edit them into your app if you prefer doing things manually! ↩
-
Lygia currently hosts two versions of WebGPU shaders. The newer versions use the WESL language and have a
.weslsuffix. For new Lygia users, we recommend.wesl. (The older versions use a.wgslsuffix, but are less complete and use a custom#includesyntax.) ↩