Build, bundle & ship your Rust WASM application to the web.

Overview

Trunk

Build Status Discord Chat

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. Browser reloading, HMR, and other related features are in-progress.

Getting Started

Head on over to the Trunk website, everything you need is there. A few quick links:

Examples

Check out a few of the example web applications we maintain in-repo:

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.

Comments
  • WASM Plugin / extension system

    WASM Plugin / extension system

    Abstract

    Given that there will always be new features that folks want to add to Trunk, but adding too much to Trunk core would cause a fair amount of bloat, we will eventually want to expose a plugin system. The following is a non-exhaustive list of what we would like to see from the plugin system (please comment below if you would like to add or remove items):

    • Ability for users to create their own plugins which will be loaded by the Trunk CLI and will be called as part of the standard Trunk build pipeline.
    • Ability for plugins to declare the asset types which they will operate on.
      • In the source HTML, this should be declared as something like <link data-trunk data-plugin rel="my-plugin-type" any-other-attrs="will be passed to plugin"/> (this needs further discussion).
      • Trunk should see that the link is a plugin, and then will call any registered plugin which matches the rel="my-plugin-type".

    The Trunk team should build and maintain a trunk-plugin library which exposes common types used by Trunk itself, and which plugins should use to facilitate communication between Trunk and the plugin. Big shoutout to @lukechu10 for pointing out that WASM is perfect for this.

    • This library will expose types needed to declare the Trunk ABI version which the plugin is using. This will allow us to safely evolve the plugin ABI without breaking old plugins.
    • Which runtime should we use? Personally I like wasmer a lot. I've used it a bit and it is pretty solid. A lot of other folks in the WASM community outside of the Rust context are using it as well.
    • What should the ABI look like which the WASM plugin modules need to expose?
    • What are the ABI capabilities which Trunk should expose to plugins? This is gonna be a big item for discussion.

    We need to gather some feedback.

    • What do folks want to do with these plugins? This is nothing new. Many of the build/bundle tools in the JS ecosystem have plugin systems.
    • What sort of data will the plugins need?
    • What should our algorithm be for plugin discovery?

    We will also want to discuss what Trunk itself should do in order to aid plugin authors in compiling, optimizing and publishing their WASM-plugins.

    There is a lot to discuss here.

    discussion needs design 
    opened by thedodd 17
  • Watch include exclude

    Watch include exclude

    This adds the --watch <path>... option to the serve and watch subcommands which allows to watch specific folder(s) or file(s).

    Closes #93

    Checklist

    • [x] Updated CHANGELOG.md describing pertinent changes.
    • [x] ~~Updated README.md with pertinent info (may not always apply).~~
    opened by malobre 16
  • Support for including Web Workers

    Support for including Web Workers

    My reference for this issue is Yew's multi_thread example which requires two WASM binaries. One for the actual application and one for the Web Worker. Up until now building applications with web workers has been a real pain but with trunk we have the chance to turn this around.

    Requirements

    The following is an objective list of problems that need to be solved to support Web Workers.

    1. Multiple binary targets

    Trunk should handle crates with multiple binary targets gracefully. Currently, invoking trunk serve on the aforementioned example results in this error:

    could not read file `$TARGET/wasm32-unknown-unknown/debug/multi_thread.wasm`
    📡 server running at http://127.0.0.1:8080/
      ❌ build finished with errors
    

    The multi_thread.wasm could not be found because there are two WASM binaries called app.wasm and worker.wasm. While it isn't strictly related to this issue, I think this behaviour could be improved.

    2. Letting the app know where to find the Web Worker

    Because of how Web Worker are created[link] we need to know the URL of the worker's Javascript file while compiling the app.

    3. Building Web Workers with the required Javascript code to start them

    Trunk currently runs wasm-bindgen with --target=web. The generated js code exports an initializer function which needs to be called to start the program. This doesn't work for Web Workers as they need to be self-executing.

    Proposal

    This is just one potential way of solving the issues mentioned above to get the discussion started.

    Since Trunk already has a config file, I think it makes perfect sense to use it for this. We add a new section to [build], let's call it "targets", which is used to configure binary targets. To take care of 3., we can simply build the WASM with --target=no-modules. Since we still want to have normal binaries, let's give each target a type key with the following two values:

    • "script" - The default value, this represents the current strategy. Builds the binary with --target=web and includes it in index.html.
    • "worker" - The new strategy which builds the value with --target=no-modules. The output is moved to dist/ but not added to index.html

    For 2. we need to allow targets to side-step hashing so we can assign static URLs to them. In the future this could use a similar approach to #9 so we don't miss out on caching, but for now we can just add a key "output" to the target which manually sets the output path.

    This is what it would look like when applied to the multi_thread example:

    [build.targets.app]
    type = "script"
    
    [build.targets.worker]
    type = "worker"
    output = "worker.js"
    

    Trunk should reject projects with multiple binaries (without appropriate configuration) outright and point the user to documentation on the subject. It might be tempting to guess which binary is which based on certain keywords (like "app" and "worker") but this probably does more harm than good in the long run. This satisfies 1..


    This is quite a high priority feature for Yew and I would love to help out with this.

    cli assets discussion needs design 
    opened by siku2 15
  • Add web worker support

    Add web worker support

    Fixes #46

    I started work on this because it looks like #167 is stalled. I took some inspiration from it, but I ended up with a different design that solves some of the questions joshyrobot raised.

    Instead of a separate rel="rust-worker" asset type, which duplicates a lot of attributes and code, I made a data-type attribute for rel="rust" which can be either main or worker. For backwards compatibility reasons I made main the default, even though it complicates the code a bit. Workers are built with wasm-bindgen --no-modules, and a small wrapper is included that loads the hashed module. The wrapper is named after the binary name if provided, otherwise the project name. I have also used this name to make the logs and file names clearer, as it got confusing fast when multiple modules were named index-{hash}.

    My use case for this is for use in a yew project. I have tested it with a private yew project, but annoyingly it requires a PR to yew as well, to tell it to use the trunk generated wrapper instead of creating a new one. I'll probably create that one if some variant of this PR gets merged.

    Feel free to bikeshed both the design and implementation. I suspect there might be considerations related to e.g. #203 and the issues it links that are relevant to this.

    Checklist

    • [x] Updated CHANGELOG.md describing pertinent changes.
    • [x] Updated README.md with pertinent info (may not always apply).
    • [x] Updated site content with pertinent info (may not always apply).
    • [x] Squash down commits to one or two logical commits which clearly describe the work you've done. If you don't, then Dodd will 🤓.
    opened by kristoff3r 12
  • Invoke wasm-opt only in release mode?

    Invoke wasm-opt only in release mode?

    I successfully installed wasm-opt from binaryen and can include data-wasm-opt="4" in my index.html, which brings the wasm size down by a factor of 60% for a simple hello world project in release mode.

    But since wasm-opt takes quite a bit of time, I don't want to do that in debug mode. Is there a way to only use that option in --release mode? The very ugly way is to have a separate index-release.html and possibly Trunk.release.toml referencing that file.

    I see several paths forward, e.g. looking for Trunk.release.toml (or variants) and treating that as an override to the general Trunk.toml, or preprocessing index.html in some way to allow for dynamic replacements.

    discussion 
    opened by WorldSEnder 12
  • Support feature flags via CLI close #60

    Support feature flags via CLI close #60

    Checklist

    • [x] Updated CHANGELOG.md describing pertinent changes.
    • [x] Updated README.md with pertinent info (may not always apply).
    • [x] Squash down commits to one or two logical commits which clearly describe the work you've done.

    This PR extends #166 to add data-cargo-all-features and data-cargo-no-default-features as well as CLI options for these build-config options.

    ~~Notice~~ ~~This is (obviously) a work-in-progress.~~ ~~I'll be using (and modifying) the work done in #166 and introduce --all-features and --no-default-features.~~ ~~In a future PR, I may even add support for that via a <link data-trunk> tag (extending #166 to "all" and "no-default").~~

    opened by Bernd-L 12
  • Auto-download required binaries

    Auto-download required binaries

    Very first version of the auto-download feature. Still mostly WIP, just opened this to show @thedodd what I've got so far and to use it as base for further discussion.

    Current status:

    • [x] Automatically download binaries for sass, wasm-bindgen and wasm-opt.
      • sass-rs depends on libsass which is now deprecated in favor of dart-sass. Turns out the CSS output directly became a bit smaller in my projects as a nice side effect. Therefore, added dart-sass to the list of external tools to download & use.
    • [x] Allow setting a specific version to install.
    • [x] Detect wasm-bindgen version from Cargo.lock as the depending version and wasm-bindgen-cli version have to strictly match.
    • [x] Allow to configure custom versions through Trunk.toml.
    • [x] Move progress logs into the download logic.
    • [x] Lots of code cleanup.
    • [x] Lookup system installed binary and match version to avoid download if possible.

    Checklist

    • [x] Updated CHANGELOG.md describing pertinent changes.
    • [x] Updated README.md with pertinent info (may not always apply).
    opened by dnaka91 12
  • Fix infinite Watch Loop (Related to PR #84)

    Fix infinite Watch Loop (Related to PR #84)

    This is my attempt at fixing the infinite watch loop described in PR #84

    It Canonicalizes all the files and folders correctly so the watcher doesn't keep rebuilding the app.

    Checklist

    • [x] Updated CHANGELOG.md describing pertinent changes.
    opened by granitrocky 12
  • SSE | WebSockets for auto-reload (future: HMR)

    SSE | WebSockets for auto-reload (future: HMR)

    • [x] open the URL in the browser, only do once per invocation of the CLI.
    • [x] use WebSocket to communicate with browser app to trigger reloads.
    • [x] ~~use WebSocket to do WASM HMR (this will probably be a beast, may not even be browser supported quite yet, we'll see).~~ We can look into HMR in the future as WASM module linking stabilizes.
    enhancement cli 
    opened by thedodd 12
  • Dodrio JS utility import responds with mime type text/html

    Dodrio JS utility import responds with mime type text/html

    Tide is supposed to have "mime type guessing", which should be able to handle a .js extension I'd think. https://github.com/http-rs/tide/pull/461/files

    mime_guess crates has a application/javascript https://github.com/abonander/mime_guess/blob/master/src/mime_types.rs

    discussion 
    opened by nkconnor 11
  • How do I attach a function to window?

    How do I attach a function to window?

    Newbie here.

    Previously I use wasm-pack doing this:

    <script type="module">
        console.log("Initializing wasm...")
        import init, { my_set_panic_hook, my_function, MyStruct } from './pkg/my_project.js';
        await init();
        my_set_panic_hook();
        console.log("Initialized.");
    
        window.my_function= my_function; 👈
        window.MyStruct = MyStruct; 👈
    </script>
    <script>
        window.my_function(); 👈
        window.MyStruct.new(); 👈
    </script>
    

    What's the equivalent pub fn main() using trunk?

    And if this is not the right way to call wasm function from js, what is?

    question 
    opened by WestXu 10
  • Not compiling with Ruby Sass

    Not compiling with Ruby Sass

    I had an issue with the arg --no-source-map since I had Ruby sass (v 3.7.4) installed which uses --sourcemap=none instead.

    I fixed it by simply uninstalling Ruby sass.

    I cloned the repo but don't feel comfortable enough with the code-base to contribute, but the option is being set at line 78 in sass.rs.

    I would Imagine a fix would consist of either forcing the use of dart-sass, alternatively to add an exception for Ruby Sass.

    Hope this is helpful in any way, and sorry for not being able to contribute with a PR. Very new to Rust.

    bug cli 
    opened by knirb 1
  • I/O error: operation failed to complete synchronously

    I/O error: operation failed to complete synchronously

    Facing this issue when I trunk serve the basic app that I created

    Logs when I run trunk serve:

    2022-09-19T08:10:39.846325Z  INFO  starting build
    2022-09-19T08:10:39.853442Z  INFO spawning asset pipelines
    2022-09-19T08:10:42.848793Z  INFO copying & hashing css path="\\\\?\\E:\\
    Rust+Wasm\\yew-video-streaming\\style.css"
    2022-09-19T08:10:42.849688Z  INFO building yew-video-streaming
    2022-09-19T08:10:42.860504Z  INFO finished copying & hashing css path="\\\\?\\E:\\Rust+Wasm\\yew-video-streaming\\style.css"
        Finished dev [unoptimized + debuginfo] target(s) in 1.41s
    2022-09-19T08:10:44.395147Z  INFO fetching cargo artifacts
    I/O error: operation failed to complete synchronously
    
    

    Let me know if anybody know why this happens?, and also the solution for this.

    investigate 
    opened by Immanuel-Codoid 2
  • Unable to build yew examples

    Unable to build yew examples

    Pardon the yew issue, but believe is trunk related.

    I've attempted building 3 example projects, one from docs, another from examples, and my own implementation.

    All result in the same error:

    2022-09-18T15:26:28.673358Z  INFO 📦 starting build
    2022-09-18T15:26:28.674514Z  INFO spawning asset pipelines
    2022-09-18T15:26:28.675514Z ERROR ❌ error
    error from HTML pipeline
    
    Caused by:
        0: error getting cargo metadata
        1: failed to start `cargo metadata`: No such file or directory (os error 2)
        2: No such file or directory (os error 2)
    2022-09-18T15:26:28.677608Z  INFO 📡 serving static assets at -> /static
    2022-09-18T15:26:28.677644Z  INFO 📡 server listening at http://127.0.0.1:8080
    

    I have the wasm32-unknown-unknown toolchain

    $ rustup show
    Default host: x86_64-unknown-linux-gnu
    rustup home:  /home/admin/.rustup
    
    installed targets for active toolchain
    --------------------------------------
    
    thumbv7em-none-eabi
    thumbv7em-none-eabihf
    wasm32-unknown-unknown
    x86_64-unknown-linux-gnu
    
    active toolchain
    ----------------
    
    stable-x86_64-unknown-linux-gnu (default)
    rustc 1.62.1 (e092d0b6b 2022-07-16)
    
    $ trunk -V
    trunk 0.16.0
    

    Running arch linux, maybe platform related? Dunno. Brand new to trunk/yew.

    investigate 
    opened by JacksonUtsch 3
  • feature request: css-modules support

    feature request: css-modules support

    For example, vite support css modules.

    import classes from './example.module.css'
    document.getElementById('foo').className = classes.red
    

    I think it will be great if trunk can support this, also.

    disposition:close 
    opened by xiaoxiangmoe 3
  • Using WASI + Asyncify?

    Using WASI + Asyncify?

    I've been working on building a webapp with egui and eframe, and the stock template comes with trunk. I've actually grown quite fond of trunk and would like to keep using it.

    I have been going through a lot of headache for the past two days trying to deal with async functions from javascript in a completely synchronous codebase, all of which involve interacting with the filesystem. WASI provides functions for accessing the filesystem, which is quite amazing, and would save me a lot of time and headache if I could use it.

    How can I use WASI? I've seen some discussion around a 'plugin system' but that idea seems to have gone nowhere.

    UPDATE: I did some digging around and found out about Asyncify, which would quite useful here.

    opened by Speak2Erase 4
Releases(v0.16.0)
Rust / Wasm framework for building client web apps

Yew Rust / Wasm client web app framework Documentation (stable) | Documentation (latest) | Examples | Changelog | Roadmap | 简体中文文档 | 繁體中文文檔 | ドキュメント A

Yew Stack 23.6k Sep 20, 2022
The simplest build-time framework for writing web apps with html templates and typescript

Encoped A build-time fast af tool to write static apps with html and TypeScript Features Template-based ESLint, Prettier and Rollup integration No ext

null 1 Dec 11, 2021
Experiments with Rust CRDTs using Tokio web application framework Axum.

crdt-genome Synopsis Experiments with Rust CRDTs using Tokio web application framework Axum. Background Exploring some ideas of Martin Kleppmann, part

dougfort 3 Mar 18, 2022
a port of yaxpeax-dis that runs as a web application

this a rough translation of yaxpeax-dis, the CLI tool, to instead accept architectures and data to disassemble as an HTTP request. the package is then deployed to dis.yaxpeax.net as a [email protected] application.

iximeow 5 Aug 8, 2021
A web application to configuration Caddy based on MoonZoon.

Cream A web application to configuration Caddy based on MoonZoon. MoonZoon is a Rust Fullstack Framework. Live demo Run on a local machine Check you'v

Tw 4 Sep 19, 2022
Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust.

Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust.

Actix 15.3k Sep 27, 2022
Sauron is an html web framework for building web-apps. It is heavily inspired by elm.

sauron Guide Sauron is an web framework for creating fast and interactive client side web application, as well as server-side rendering for back-end w

Jovansonlee Cesar 1.7k Sep 26, 2022
Hot reload static web server for deploying mutiple static web site with version control.

SPA-SERVER It is to provide a static web http server with cache and hot reload. 中文 README Feature Built with Hyper and Warp, fast and small! SSL with

null 6 Aug 17, 2022
Oso is an open source policy engine for authorization that’s embedded in your application

Oso What is Oso? Oso is an open source policy engine for authorization that’s embedded in your application. It provides a declarative policy language

oso 2.7k Sep 30, 2022
Build controllers for the Webots robot simulator in Rust

Webots controllers in Rust Status: experimental This is a reference project that shows how to build controllers for the Webots robot simulator using t

Adam Jensen 13 Jun 27, 2022
A Rust application which funnels external webhook event data to an Urbit chat.

Urbit Webhook Funnel This is a simple Rust application which funnels external webhook event data to an Urbit chat. This application is intended to be

Robert Kornacki 15 Jan 2, 2022
Sample serverless application written in Rust

This is a simple serverless application built in Rust. It consists of an API Gateway backed by four Lambda functions and a DynamoDB table for storage.

AWS Samples 132 Sep 21, 2022
Reference implementation of a full-stack Rust application

Full-stack Rust with WebAssembly Look Ma, No JavaScript !!! My very first Rust project (implementation of the "Connect 5" game), I used as a learning

Vassil 54 Sep 28, 2022
The official DAW application of the RustyDAW project (name in progress)

rusty-daw-application The official DAW application of the RustyDAW project (name in progress) Take a look at the design doc. Join our community at the

null 15 Jun 14, 2021
Starknet application for Ledger Nano S, SP, X

Ledger Starkware app Please visit our website at zondax.ch This project contains the Starkware app (https://starkware.co/) for Ledger Nano S and X. Le

Ledger 12 Sep 8, 2022
A Rust web framework

cargonauts - a Rust web framework Documentation cargonauts is a Rust web framework intended for building maintainable, well-factored web apps. This pr

null 178 Jun 22, 2022
A Rust library to extract useful data from HTML documents, suitable for web scraping.

select.rs A library to extract useful data from HTML documents, suitable for web scraping. NOTE: The following example only works in the upcoming rele

Utkarsh Kukreti 807 Sep 26, 2022
A rust web framework with safety and speed in mind.

darpi A web api framework with speed and safety in mind. One of the big goals is to catch all errors at compile time, if possible. The framework uses

null 32 Apr 11, 2022
A web framework for Rust.

Rocket Rocket is an async web framework for Rust with a focus on usability, security, extensibility, and speed. #[macro_use] extern crate rocket; #[g

Sergio Benitez 18.4k Sep 20, 2022