Publishing Packages
#Naming Conventions
Prefer
_(underscore) over-(dash) in package names. Embedded-characters aren’t allowed in WGSL and WESL identifiers (it would create ambiguity with minus).Name shader packages with a
_wgslsuffix to make shader packages easy to find when searching.Add
keywords["WGSL", "WESL", "WebGPU"]incargo.tomlandpackage.jsonto make packages easy to find when searching.
#Publishing a package to npm.js
Use wesl-packager to gather WGSL and WESL shader modules into an npm package.
#Command Line Tools
Here’s an example, creating a bundled package in the dist directory
from sources in the src/shaders directory.
npx wesl-packager --rootDir src/shaders --outDir dist
Add the files generated by wesl-packager to the package’s package.json:
/// in package.json
"exports": {
".": {
"types": "./dist/weslBundle.d.ts",
"import": "./dist/weslBundle.js"
}
},
#npm Shader Package Format
The format generated for shader packages (and consumed by the WESL JavaScript/TypeScript tools) is a WeslBundle:
export interface WeslBundle {
/** name of the package, e.g. random_wgsl */
name: string;
/** wesl edition of the code e.g. unstable_2025_1 */
edition: string;
/** map of wesl/wgsl modules:
* keys are file paths, relative to package root (e.g. "./lib.wgsl")
* values are wgsl/wesl code strings
*/
modules: Record<string, string>;
/** packages referenced by this package */
dependencies?: WeslBundle[];
}
Shaders are bundled simply as strings with relative file paths in the modules field.
dependencies reference import statements in the js output bundle
so that shader packages can depend on other packages.
Shader dependency versioning is handled by the package manager.
#Importing and lib.wesl
npm package users can easily use the shader package in their own shaders.
For a new package called foo_wgsl:
npm add foo_wgslimport from the package in WESL, using module paths with
::separators:import foo_wgsl::util::foo; fn main() { foo();` }
To keep things short, the special module name lib.wesl is addressable at the root level of the package:
fn main() {
foo_wgsl::bar();`
}
#wesl-packager Options
The wesl-packager has some options:
#Location for Files
–src WGSL/WESL shader files to bundle into the package, using glob syntax. (default:
./shaders/*.w[eg]sl)–rootDir base directory containing WGSL/WESL files. The source files are mapped to imports starting at the base directory. (default:
./shaders)–outDir where to put bundled output files relative to
projectDir(default: “dist”)–projectDir directory containing package.json (default: current directory).
#Shader Bundling Mode
- –multiBundle Make a shader bundle for each source file (instead of a single bundle for all shader files). (default no-multiBundle)
#Writing Entries into Package.json
–updatePackageJson write ‘exports’ entries into package.json (default: no-updatePackageJson ]
–exportName
package.jsonexport name for this consolidated bundle. This flag is ignored for multiBundle mode. (default: “.”).
#Publishing a Package to crates.io
See rust example here