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 Tanja-4732 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
  • trunk logging cannot be tuned by `RUST_LOG` (or another environment variable)

    trunk logging cannot be tuned by `RUST_LOG` (or another environment variable)

    I am currently using trunk as the frontend bundler for stackable which is an SSR-capable framework for Yew.

    However, there are 5 different styles of logging mixed in the output in the development server:

    1. cargo (build log)
    2. cargo make (task log)
    3. stackctl (progress log)
    4. application server (access log)
    5. trunk (frontend build log)

    This makes logging to look kind of messy. I wish the logging to have a consistent style:

    1. cargo (build log)
    2. stackctl (general progress log & development server ready message)
    3. application server (access log)

    I have currently suppressed stdout and stderr of cargo and trunk because there is not a way to modify trunk logging's style or logging level. However, this can make the build process to become a little bit painful when users run the development server for the first time as there will be no progress made on the screen for a couple minutes until frontend and backend complete building.

    I think the proper way to solve this is with #207, however, I wish a solution can be put together sooner to improve logging.

    Would it possible to make trunk logging to be tunable by RUST_LOG or TRUNK_LOG?

    opened by futursolo 1
  • Allow empty HTML file input and dist dir config.

    Allow empty HTML file input and dist dir config.

    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 🤓.

    Related to #342.

    opened by langyo 0
  • Support relative public URLs

    Support relative public URLs

    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 🤓.

    As longly requested in #361, this should make it possible to use relative URLs for the public-url setting, while not breaking the Axum route at the same time.

    The adjustment for the public URL is now a bit more relaxed, so that it only corrects trailing slashes and allows for various relative paths in the front. Then, later on the Axum router uses a fake Url as base to join against the given public URL. This will resolve it into an absolute URL that should work as route path.

    • / -> / -> axum /
    • ./ -> ./ -> axum /
    • ../ -> ../ -> axum /
    • test/../a/// -> test/../a/ -> axum /a

    The prefixing of the public URL with a /, is not needed anymore, unless there is some case I might have not thought of?

    opened by dnaka91 1
  • Add a `quiet` field to hooks

    Add a `quiet` field to hooks

    Hi!

    I was wondering if it would be possible to add a field named quiet: bool to hooks which output a lot of useless information, not showing the output of the hook.

    opened by vidhanio 1
  • Releasing new features?

    Releasing new features?

    Hey!

    I'm curious, what's blocking a new trunk release? I'm seeing in the changelog that script handling is unreleased, and it seems to me that it's the one thing missing to be able to actually use trunk well for development: without it, it's basically impossible to vendor JS libraries alongside the app (eg. to include the bootstrap javascript without relying on a network request to a CDN)

    Or am I missing another way to do it with trunk 0.16?

    Anyway, thank you for trunk, it's been a huge help in my first steps into web programming in rust!

    opened by Ekleog 2
Releases(v0.16.0)
Bundle Shiny Applications for serving with WebR.

WebR Bundle A tool for bundling Shiny Apps with WebAssembly. R Package Installation Install the package from GitHub: # install.packages("pak") pak::pa

Andrés Felipe Quintero Moreano 12 Oct 5, 2023
Bundle Shiny Applications for serving with WebR.

WebR Bundle A tool for bundling Shiny Apps with WebAssembly. R Package Installation Install the package from GitHub: # install.packages("pak") pak::pa

Appsilon 14 Oct 29, 2023
Code template for a production Web Application using Axum: The AwesomeApp Blueprint for Professional Web Development.

AwesomeApp rust-web-app More info at: https://awesomeapp.dev/rust-web-app/ rust-web-app YouTube episodes: Episode 01 - Rust Web App - Course to Produc

null 45 Sep 6, 2023
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 25.8k Jan 2, 2023
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
Web Application with using Rust(Actix, Diesel and etc)

Santa Service App Used technology stack Web Server with using Rust (Actix, Actix-web, Diesel) Data base (Postgres) Console Application (Tokio) Tasks o

null 3 Jan 8, 2023
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 compute@edge 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
Extremely simple Axum + SolidJS starter for a fullstack web application.

royce Extremely simple Axum + SolidJS starter for a fullstack web application. Deploy immediately with a ready-to-use preconfigured Docker deployment.

null 39 Oct 16, 2024
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 16.2k Jan 2, 2023
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 Dec 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 7 Dec 18, 2022
A highly customizable, full scale web backend for web-rwkv, built on axum with websocket protocol.

web-rwkv-axum A axum web backend for web-rwkv, built on websocket. Supports BNF-constrained grammar, CFG sampling, etc., all streamed over network. St

Li Junyu 12 Sep 25, 2023
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.8k Jan 4, 2023
Axum + JWT authentication Middleware that allows you to start building your application fast

axum_jwt_ware Integration Guide Simple Axum + JWT authentication middleware with implemented Login and refresh token. Goal I aim to simplify the proce

Eze Sunday 3 Dec 2, 2023
Proof of concept writing a monolith BBS using Rust, GraphQL, WASM, and SQL. WILL BE ARCHIVED ONCE PROVEN

GraphQL Forum Important DO NOT even think about using this in production, lest your sanity be destroyed and credentials lost! Loosely following the aw

Rongcui Dong 25 Apr 25, 2023
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 14 Oct 11, 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