Introduction: Run your JavaScript on WebAssembly. Javy takes your JavaScript code, and executes it in a WebAssembly embedded JavaScript runtime.
Javy is currently used for the beta Shopify Scripts platform. We intend on supporting and improving this runtime in that context. Eventually this project should be a good general purpose JavaScript runtime but that is not the current goal.
Javy is a beta project and will be under major development. We welcome feedback, bug reports and bug fixes. We're also happy to discuss feature development but please discuss the features in an issue before contributing. All contributors will be prompted to sign our CLA.
- rustup
- Stable Rust (
rustup install stable && rustup default stable
) - wasm32-wasi, can be installed via
rustup target add wasm32-wasi
- cmake, depending on your operating system and architecture, it might not be
installed by default. On Mac it can be installed with
homebrew
viabrew install cmake
- Rosetta 2 if running MacOS on Apple Silicon, can be installed via
softwareupdate --install-rosetta
- Install the
wasi-sdk
by runningmake download-wasi-sdk
- wasmtime-cli, can be installed via
cargo install wasmtime-cli
(required forcargo-wasi
) - cargo-wasi, can be installed via
cargo install cargo-wasi
After all the dependencies are installed, run make
. You
should now have access to the executable in target/release/javy
Alternatively you can run make && cargo install --path crates/cli
.
After running the previous command you'll have a global installation of the
executable.
Define your JavaScript like:
function foo(input) {
return { foo: input.n + 1, newBar: input.bar + "!" };
}
Shopify = {
main: foo,
};
Create a WebAssembly binary from your JavaScript by:
javy index.js -o destination/index.wasm
For more information on the commands you can run javy --help
You can then execute your WebAssembly binary using a WebAssembly engine:
$ echo '{ "n": 2, "bar": "baz" }' | wasmtime index.wasm
{"foo":3,"new_bar":"baz!"}%
Javy-generated modules are by design WASI only and follow the command pattern. Any input must be passed via stdin
and any output will be placed in stdout
. This is especially important when invoking Javy modules from a custom embedding.
In a runtime like Wasmtime, wasmtime-wasi can be used to set the input and retrieve the output.
The quickjs-wasm-rs
crate that is part of this project can be used as part of a Rust crate targeting Wasm to customize how that Rust crate interacts with QuickJS. This may be useful when trying to use JavaScript inside a Wasm module and Javy does not fit your needs as quickjs-wasm-rs
contains serializers that make it easier to send structured data (for example, strings or objects) between host code and Wasm code.
- Create a tag for the new version like
v0.2.0
git tag v0.2.0
git push origin --tags
- Create a new release from the new tag in github here.
- A GitHub Action will trigger for
publish.yml
when a release is published (i.e. it doesn't run on drafts), creating the artifacts for downloading. However this does not currently supportarm-macos
, ie. M1 Macs. - Manually build this on a m1 mac
gzip -k -f target/release/javy && mv target/release/javy.gz javy-arm-macos-v0.2.0.gz
- Manually create the shasum file
shasum -a 256 javy-arm-macos-v0.2.0.gz | awk '{ print $1 }' > javy-arm-macos-v0.2.0.gz.sha256
- Attach both files to the new release page