shadplay: a live WGSL scratchpad for learning Bevy shaders
Real-time wgsl visualisation tooling for educating oneself in the art of shader programming
At a glance
- What is it?
- shadplay is a small Rust application that gives you a window with shader code applied to Bevy mesh geometry, recompiling on save so you can see a change immediately. It is built for people learning WGSL for Bevy, it carries a searchable copy of the Bevy shader library because the WGSL language server story is weak, and it is a research and teaching tool rather than a finished product.
- Who is it for?
- Adopt shadplay if you are learning WGSL for Bevy and want a tight edit and see loop, since the file watcher recompiles the shader the moment you save and the window stays on top of your editor, which removes the rebuild cycle that makes shader learning slow. Do not adopt it as a production shader pipeline, because the crate version is 0.0.5, it depends on a specific Bevy release, and the tool is aimed at exploring rather than shipping.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 14 days ago.
- What is it written in?
- Mainly WGSL, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the window actually does
The project describes itself as real-time WGSL visualisation tooling for educating oneself in the art of shader programming, and it is an app rather than a library.
The core idea is small. Shadplay gives you a window, applies the shader code you are writing to Bevy mesh geometry, and recompiles when you save. The crate description puts it plainly: it provides a window where shader code is applied to Bevy mesh geometry, and the primary goal is to allow users to see immediate changes to their shader code, achieved by leveraging Bevy's file-watcher system, which automatically recompiles and updates the shader on the mesh whenever the user saves their changes in their editor of choice.
The stated goal is the lowest barrier to entry for individuals who want to learn or practise using WGSL, the WebGPU Shading Language, for the purpose of doing work in Bevy.
That last clause is what defines the project. This is not a general shader playground. It is a teaching tool for a specific language and a specific engine, and the Bevy dependency is not incidental to that.
The primary language in the repository metadata is WGSL, which tells you where the content of the repository actually lives.
The three goals: learn WGSL, port GLSL work, surface Bevy's builtins
The readme states three goals in ascending order of importance to the author, and each is a different kind of work.
The primary goal is learning wgsl with minimal friction, specifically for those wanting to learn wgsl to write shaders for Bevy.
The secondary goal is to flesh out a relatively comprehensive port of existing shader work from places like shadertoy, because there are a few gotchas around the differences in glsl and wgsl syntax and their respective builtins. The porting burden is the interesting part here. A shader written for Shadertoy assumes GLSL conventions that WGSL does not share, and a shader written for Bevy assumes a set of builtins that exist only inside Bevy. Moving between those worlds is a real, unglamorous job, and doing it once for a community saves everyone else the work.
The tertiary goal is to surface the builtins and existing library code that the Bevy codebase provides.
And then the reason that tertiary goal matters most, stated directly: a large swath of the wgsl code from the Bevy codebase is included in the repository, because the authors want it available and searchable within your IDE, as the lsp story for wgsl is not a great one, yet.
That last sentence is the real justification for the repository. A language server for WGSL is not good enough, so the workaround is to vendor the source.
The live preview loop, driven by Bevy's file watcher
The dependency list in Cargo.toml shows how little machinery is involved. Bevy is pulled in with the file_watcher and jpeg features, bevy_egui is an optional dependency behind a default ui feature, and the rest is a small set of utility crates: anyhow for errors, argh for command line parsing, chrono for timestamps, copypasta for the clipboard, directories for paths, image, serde with derive, and toml.
Two of those choices map directly onto features in the readme. The image crate and the jpeg feature are for dragging in textures. The copypasta crate is behind the colour picker, which gives you an immediate vecf3(r, g, b) value for quick use. The directories crate is for the screenshot versioning, and chrono supplies the timestamp in the folder name.
The dev-dependencies section is worth noting too, because it shows what a development build adds. Bevy is re-declared with file_watcher, jpeg and dynamic_linking, and the build dependencies pull in reqwest with tokio and glob and futures.
Those build dependencies are for the code generation step. The scripts/ directory contains scripts to pull all the functions from the Bevy codebase's shader code so you can easily look up what is available for import, and scripts to search the Bevy source code, opening your browser, for specific keywords. The readme points to scripts/README.md for both. The result is checked into the repository as all_wgsl.wgsl, alongside bevy-shader-book.md, bevy-shaders-cheatsheet.md and hitlist.txt.
Screenshots that version the shader alongside the image
One feature is unusual enough to be worth describing on its own. Pressing the spacebar takes a screenshot of the shader you are working on, and it also versions the shader file, so the snapshot and the source that produced it stay together:
screenshots
└──| 01-10-23
└──| 09-23-29
├──| screenshot.png // Your screenshot
└──| screenshot.wesl// The shader at `assets/shaders/myshader.wesl`The structure is a date folder, then a time folder, then the image and the shader side by side. The two-level timestamp means a single day can hold many captures without collision.
The rationale is that a shader is a visual artefact, and a PNG of a shader without the shader that made it is close to useless. A GIF is the same idea in motion, and the app supports continuous image capture to create gifs, currently limited to a maximum framerate of 20FPS for capture, with a link to a guide on using ffmpeg for higher quality output.
The shader files in the repository use the .wesl extension, as in assets/shaders/yourshadergoeshere.wesl and the versioned copies above, and the app also accepts valid wgsl dropped onto the window.
This is a small thing, and it is the kind of small thing that makes a learning tool pleasant to use.
The hotkey table, and its small inconsistencies
The keybindings are listed in a table, and they tell you how the app is meant to be used, which is hands-on rather than menu-driven.
q quits, s changes the shape in 3D, tab toggles the colour picker, t switches to 2D or ShaderToy mode, h switches to 3D, and spacebar takes a screenshot and versions the current .wesl file. Return takes screenshots continuously until you press it again to stop the capture. The digits 0 to 9 select a texture at that index, which is how you switch between dropped images. Question mark opens the help interface.
There are a few rough edges in the table that are worth knowing before you rely on them. The key t appears twice with two different meanings, once for the 2D or ShaderToy mode switch and once for toggling transparency. The l binding is listed simply as Window-Level with no action described. The x binding is marked WINDOWS ONLY and toggles window fallthrough in 3D, and d toggles decorations with a note that this does not work on all operating systems, and b toggles the border in 2D only. The transparency toggle carries an explicit caveat that returning to fully transparent is not supported, and the r binding rotates the shape in 3D only.
The transparency limitation is the one that would actually stop you shipping a screensaver-like use case, which is what the SCREENSAVER.md file in the repository suggests the author had in mind.
Building it, and what the toolchain requires
The requirements section is short, and the one entry that matters is the toolchain. To run shadplay you need Rust, nightly, and the readme links to the Rust installation instructions.
The nightly requirement is consistent with the rest of the repository. There is a rust-toolchain.toml and a toolchain.toml at the root, plus a .cargo/ directory, a Cargo.lock, a flake.nix with a flake.lock, and a .envrc, which together describe a project set up to a specific toolchain rather than left to whatever the developer happens to have. There is also a clippy.toml, a .typos.toml for spell checking, a .rules.toml, and a .pre-commit-style set of developer tooling.
The crate itself is version 0.0.5, edition 2024, and it depends on Bevy 0.20.0. That version pairing is the thing to check first, because a Bevy application that pins a specific engine release does not float with the engine, and the file watcher feature it relies on is part of what it pins.
The Cargo.toml also declares an example named might, at examples/might/src/main.rs, with an examples/README.md beside it, and the repository has an examples/ directory containing only that one example.
The crate description is written to be a complete answer to what the project is, and the manifest also carries the author, Jeremy Webb, and the MIT licence.
Where shadplay fits against the alternatives
There are other ways to learn WGSL, and the difference is in what you give up.
The alternative in the browser is an online editor, and the difference there is that a browser sandbox has no access to the Bevy builtins, which is precisely the part shadplay exists to make available. A shader that runs in a generic web editor and a shader that runs in Bevy are not the same program, because Bevy injects its own uniform bindings and helper functions. Learning the generic case first and then discovering the gap is the exact path shadplay is trying to remove.
The other alternative is to work inside Bevy itself, by writing shaders into an actual game project. That gives you the real thing, but the iteration cost is a full application build, and the immediate feedback that shadplay provides, recompile on save, is what you give up.
There is a third dimension, which is the difference between a tool and a reference. The Bevy shader library in this repository, with the cheatsheet, the shader book, the extracted functions and the keyword search scripts that open your browser, is useful even if you never run the application. It is the part that a team with an existing Bevy project would pull in, and it addresses the same weakness the author names, that the lsp story for wgsl is not a great one yet.
The honest assessment is that this is a personal tool. Version 0.0.5, one author, one example, and a nightly toolchain requirement. The value is in the accumulated knowledge and the fast loop, not in the software being production-shaped.
Editorial conclusion
Adopt shadplay if you are learning WGSL for Bevy and want a tight edit and see loop, since the file watcher recompiles the shader the moment you save and the window stays on top of your editor, which removes the rebuild cycle that makes shader learning slow. Do not adopt it as a production shader pipeline, because the crate version is 0.0.5, it depends on a specific Bevy release, and the tool is aimed at exploring rather than shipping. Before you build, confirm you have Rust nightly installed as the readme requires, and read bevy-shaders-cheatsheet.md and bevy-shader-book.md, since the searchable Bevy shader library the app carries is the part most worth keeping even if the app itself goes unused.
Frequently asked questions
What is shadplay and who is it for?
It is a Rust application that provides a window where shader code is applied to Bevy mesh geometry, designed to give people learning WGSL for Bevy the lowest barrier to entry. It recompiles shaders automatically on save using Bevy's file-watcher system.
How do I run shadplay?
You need Rust, nightly, installed on your system, with installation instructions linked from the readme. The crate is version 0.0.5, depends on Bevy 0.20.0 with the file_watcher and jpeg features, and the repository carries a rust-toolchain.toml and toolchain.toml alongside a flake.nix for Nix users.
Does shadplay include Bevy's shader library?
Yes. A large swath of the wgsl code from the Bevy codebase is included in the repository so that it is available and searchable within your IDE, because the lsp story for wgsl is not a great one yet. Scripts in the scripts/ directory pull all the functions from the Bevy shader code and search the Bevy source for keywords.
What do the shadplay keybindings do?
q quits, s changes the 3D shape, tab toggles the colour picker, t switches to 2D or ShaderToy mode and also toggles transparency, h switches to 3D, spacebar takes a screenshot and versions the current .wesl file, return takes screenshots continuously, the digits select a texture by index, and question mark opens the help interface.
Can I use my own textures in shadplay?
Yes. You can drag and drop .png or .jpg files onto the window to use them as textures, and the digits 0 to 9 select a texture at that index once dropped. There is a how-to-texture.wesl example in assets/shaders, and a howto-mouse.wesl example that puts the mouse coordinates into a uniform.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/alphastrata-shadplay)Was this useful?