Bundler plugin for importing .wesl and .wgsl shader files in JavaScript/TypeScript.
npm install wesl wesl-plugin
Link shaders at build time for the smallest application bundle size.
// vite.config.ts
import { staticBuildExtension } from "wesl-plugin";
import viteWesl from "wesl-plugin/vite";
export default {
plugins: [viteWesl({ extensions: [staticBuildExtension] })]
};// app.ts
import wgsl from "./shaders/main.wesl?static";
const module = device.createShaderModule({ code: wgsl });Link shaders at runtime when you need dynamic conditions or constants:
// vite.config.ts
import { linkBuildExtension } from "wesl-plugin";
import viteWesl from "wesl-plugin/vite";
export default {
plugins: [viteWesl({ extensions: [linkBuildExtension] })]
};// app.ts
import { link } from "wesl";
import shaderConfig from "./shaders/main.wesl?link";
const linked = await link({
...shaderConfig,
conditions: { MOBILE: isMobileGPU },
constants: { num_lights: 4 }
});
const module = linked.createShaderModule(device, {});import viteWesl from "wesl-plugin/vite";
import esbuildWesl from "wesl-plugin/esbuild";
import rollupWesl from "wesl-plugin/rollup";
import webpackWesl from "wesl-plugin/webpack";
// Also: nuxt, farm, rspack, astroExtensions enable different import suffixes:
| Extension | Suffix | Output | Use Case |
|---|---|---|---|
staticBuildExtension |
?static |
WGSL string | Build-time linking, simplest |
linkBuildExtension |
?link |
LinkParams object | Runtime conditions/constants |
import { staticBuildExtension, linkBuildExtension } from "wesl-plugin";
import viteWesl from "wesl-plugin/vite";
export default {
plugins: [viteWesl({
extensions: [staticBuildExtension, linkBuildExtension]
})]
};For ?static, you can specify conditions as query parameters:
import wgsl from "./app.wesl?MOBILE=true&DEBUG=false&static";The plugin reads wesl.toml to find shader files and dependencies:
weslFiles = ["shaders/**/*.wesl"]
weslRoot = "shaders"
dependencies = ["auto"] # Auto-detect from package.json- SimpleReflectExtension - Demo for extension authors showing how to generate JS/TS from shader structs
import type { PluginExtension } from "wesl-plugin";
const myExtension: PluginExtension = {
extensionName: "myfeature", // enables ?myfeature imports
emitFn: async (shaderPath, api, conditions, options) => {
const sources = await api.weslSrc();
// Return JavaScript code as a string
return `export default ${JSON.stringify(sources)};`;
}
};See PluginExtension.ts for the full API.