File: README.md
Trunk
Build, bundle & ship your Rust WASM application to the web.
βPack your things, weβre going on an adventure!β ~ Ferris
Trunk is a WASM web application bundler for Rust. Trunk uses a simple, optional-config pattern for building & bundling WASM, JS snippets & other assets (images, css, scss) via a source HTML file.
π¦ Dev server - Trunk ships with a built-in server for rapid development workflows, as well as support for HTTP & WebSocket proxies.
π Change detection - Trunk watches your application for changes and triggers builds for you, including automatic browser reloading.
Getting Started
Head on over to the Trunk website, everything you need is there. A few quick links:
- Install
- Download a released binary: https://github.com/trunk-rs/trunk/releases
cargo binstall trunk(installing a pre-compiled binary using cargo-binstall)cargo install trunk --locked(compile your own binary from crates.io)cargo install --git https://github.com/trunk-rs/trunk trunk(compile your own binary from the most recent git commit)cargo install --path . trunk(compile your own binary from your local source)brew install trunk(installing from Homebrew)nix-shell -p trunk(installing from nix packages)
- App Setup
- Assets
- Configuration
- CLI Commands
Examples
Check out the example web applications we maintain in-repo under the examples directory.
Contributing
Anyone and everyone is welcome to contribute! Please review the CONTRIBUTING.md document for more details. The best way to get started is to find an open issue, and then start hacking on implementing it. Letting other folks know that you are working on it, and sharing progress is a great approach. Open pull requests early and often, and please use GitHub's draft pull request feature.
License
trunk is licensed under the terms of the MIT License or the Apache License 2.0, at your choosing.
File: examples/yew-tls/README.md
Trunk | Yew | TLS
An example application demonstrating building a WASM web application using Trunk, Yew & YBC serving with TLS enabled.
Once you've installed Trunk, simply execute trunk serve --open from this example's directory, and you
should see the following web application rendered in your browser. The application will be served using
the self-signed TLS certificates located in self_signed_certificates and configured in Trunk.toml.
Creating new self-signed certificates
[!CAUTION]
Using self-signed certificates can be fine for a local, development scenario. Using them in any other scenario may be
dangerous.
There are many ways to create self-signed certificates, here is one of them:
openssl req -new -newkey rsa:4096 -days 3650 -nodes -x509 \
-subj "/C=XX/CN=localhost" \
-keyout self_signed_certs/key.pem -out self_signed_certs/cert.pemFile: examples/yew-tailwindcss/README.md
Trunk | Yew | Tailwind
An example application demonstrating building a WASM web application using Trunk, Yew & Tailwind.
In order to run, this example requires a working nodejs installation that includes npx.
Simply execute trunk serve --open from this example's directory, and you should see the following web application rendered in your browser.
File: examples/yew/README.md
Trunk | Yew | ybc
An example application demonstrating building a WASM web application using Trunk, Yew & YBC.
Once you've installed Trunk, simply execute trunk serve --open from this example's directory, and you should see the following web application rendered in your browser.
File: examples/yaml-config/README.md
Trunk | cargo-manifest
An example application demonstrating building a vanilla Rust (no frameworks) WASM web application having the
configuration in the Trunk.yaml file instead.
Once you've installed Trunk, simply execute trunk serve --open from this example's directory, and you should see the
web application rendered in your browser.
File: examples/wasm_threads/README.md
Web Workers with shared memory, using only a single WASM binary
This is a port of the wasm_threads simple.rs example.
It should also work similarly with wasm-bindgen-rayon and other packages that use SharedArrayBuffer.
An explanation of this approach is described here.
Limitations
It has some significant advantages over the `webworker*' examples, but also some significant disadvantages.
For starters, it requires cross-site isolation (setting 2 headers), which is required for this approach to workers.
We've added it to the trunk config.
These same headers are also required for deployment. Github Pages does not allow setting headers, and alternatives such as using <meta> did not work in my tests, so these sites can't be deployed that way. Cloudflare Pages is a free alternative that does allow headers, and it worked for me.
It also requires nightly Rust, because the standard library needs to be rebuilt.
Some libraries may not work correctly in this way, as they were written assuming the historical single-threaded wasm32 runtimes. wgpuhas thefragile-send-sync-non-atomic-wasmflag which, if set, will not work with this. For example,egui` currently sets this flag, although it can be removed with a manual, not well tested patch.
Additional restrictions are listed here (some of which may be solved or worked around in libraries). Limitations specific to `wasm_thread' are explained in the source code comments.
Advantages
- Code sharing
- Improves developer experience
- Also means that the WASM binary is shared, which in extreme cases can be half the size of the deployed application.
- Avoids the web-worker cache-invalidation issue
- Memory sharing between threads
- can be a huge performance gain
Notes on applying this
Note that this requires the toolchain file and the cargo config.
The _headers file and its copy in index.html is simply an example of how to set the headers using Cloudflare Pages.
If you receive errors such as
[Firefox] The WebAssembly.Memory object cannot be serialized. The Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy HTTP headers can be used to enable this.
[Chrome] SharedArrayBuffer transfer requires self.crossOriginIsolated.
Then the headers are not set correctly. You can check the response headers on the / file in the Network tab of the browser developer tools.
Errors such as
InternalError: too much recursion
Were solved in the example by enabling optimizations. It was sufficient to do this on dependencies only, with
# in Cargo.toml
# Optimize all dependencies even in debug builds:
[profile.dev.package."*"]
opt-level = 2This will slow down clean rebuilds, but should not affect rebuild speed during normal development.
Using rust-analyzer
Since we use the build-std flag in the toolchain file, and that requires an explicit target to be set for compilation etc., this will break rust-analyzer in many setups. This can be solved by specifying an explicit target for the workspace, such as with the provided config file for vscode.
File: examples/vanilla/README.md
Trunk | Vanilla | web-sys
An example application demonstrating building a vanilla Rust (no frameworks) WASM web application using web-sys.
Once you've installed Trunk, simply execute trunk serve --open from this example's directory, and you should see the web application rendered in your browser.
File: examples/target-path/README.md
Trunk | target-dirs
An example application demonstrating create a more complex target directory structure in the dist folder, based on
the vanilla example.
Once you've installed Trunk, simply execute trunk serve --open from this example's directory, and you should see the
web application rendered in your browser.
File: examples/seed/README.md
Trunk | Seed
An example application demonstrating building a WASM web application using Trunk & Seed taken from: Seed TodoMVC Example
Once you've installed Trunk, simply execute trunk serve --open from this example's directory, and you should see the web application rendered in your browser.
File: examples/proxy/README.md
Trunk Proxy
An example demonstrating how to use the Trunk proxy system for various HTTP endpoints as well as WebSockets.
There isn't much going on in this example as far as WASM is concerned, but have a look at the Trunk.toml in this directory for exhaustive examples on how to configure and use Trunk proxies.
Setup
First, in a shell terminal, execute docker compose run --service-ports echo-server. This will start an echo server container which we will use as a generic backend for the proxies we've defined in this example.
Next, in a different shell tab or window, execute trunk serve. This will build the demo application and will ultimately start the Trunk proxies defined in the Trunk.toml.
From here, use cURL, xh, websocat or any other tool you would like to verify the proxies' functionality. All normal HTTP requests will be echoed back, and all WebSocket messages will be echoed back.