Building Progressive Web Apps using Elm and Rust

I absolutely enjoyed Elm’s workflow when doing front-end development. However, sometimes I need to run more performance-intensive functionalities or Elm does not yet have the libraries I need. Rust fills up this demand perfectly. It uses zero-cost abstraction, has no garbage collector, and has thousands of libraries for different needs. Best of all, Rust has built-in support for functional-style programming using Algebraic Data Types, higher-order functions, and closures. In addition, Rust has one of the best WebAssembly toolchains and interoperating with JavaScript is relatively easy.

I have yet to see a template or tool for creating a progressive web app using both Elm and Rust in the front end so I created one called elm-rust-template.

Features

  • Zero configuration required at startup
  • Easily port your existing Elm app with almost no modifications into a reliable PWA built on Rust’s high performance
  • Automatically optimize and minimize all assets for an extremely small production build size, 160KB demo app (50KB of code, 110KB of icons)
  • Excellent cross-platform support, see caniuse.com
  • Highly customizable, just modify webpack.config.js and package.json as you see fit

Example projects

Current issue

Future

If you know how to solve the Android PWA issue or have some ideas on how to implement new features, please tell me how or submit a PR on elm-rust-template.

20 Likes

Have you tried deploying this on heroku?

I have no backend konwledge and always sticked with Github Pages. So I never used heroku before. What’s its use case and advantages here?

Awesome to see more of this :slight_smile:
Personally, I do not come from the Web community and tend to stay away from webpack so I’m building the Rust code with wasm-pack build --target web which is does not involve webpack. I haven’t tried PWA yet though. To which extent is webpack needed in your setup?

elm-rust-template uses wasm-pack to compile Rust to WebAssembly and uses webpack to bundle the compiled WebAssembly with JavaScript, Html, and CSS into a progressive web app. The whole purpose of the template is to automate most of the steps so you don’t need to understand how to configure any of the tools. The out-of-the-box option is good enough for most use cases and you can port most existing Rust and Elm projects with relative ease. You can checkout the README for the entire build process. As a side note, you can checkout yew if you prefer a full-on Rust web framework. I personally prefer using Elm for display and most non-intensive app logic.

1 Like

Hi, Seed (Rust framework with Elm-like architecture) maintainer here.

  1. There are some problems with project initialization:
Problem A
$ cargo generate --git https://github.com/AlienKevin/elm-rust-template
 Project Name: the_first
 Renaming project called `the_first` to `the-first`...
 Creating project called `the-first`...
Error: liquid: Cannot read file
  with:
    path=C:\elm_rust\the-first\www\android-chrome-192x192.png
Problem B
/c/work/elm_rust/the-first/www
$ npm install
npm ERR! code EINVALIDPACKAGENAME
npm ERR! Invalid package name "{{project-name}}": name can only contain URL-friendly characters

(The template placeholder hasn’t been replaced in package.json -> dependencies)

Problem C
/c/work/elm_rust/the-first/www
$ npm run watch

> create-wasm-app@0.1.0 watch C:\work\elm_rust\the-first\www
> chokidar "**/*.elm" -c "elm make src/Main.elm --output elm.js && replace '\(this\)\);$' '(window
));' elm.js" --initial

add:src\Main.elm
'elm' is not recognized as an internal or external command,
operable program or batch file.
add:node_modules\the-first
Watching "**/*.elm" ..
'elm' is not recognized as an internal or external command,
operable program or batch file.

I haven’t been working with Elm for a while, so I don’t have elm compiler - I think it should be as the requirement in the README.

  1. There is a Webpack plugin for Rust compiling to WASM. It makes building and watching simpler. But there are some issues (e.g. this one) and I agree with @mattpiz that Webpack isn’t very good choice - we have Webpack template with auto-reload and prerendering for Seed, but it’s the most error-prone and complex part of the stack. So many users (including me) don’t like it very much and I’m writing Rust alternative for it. I recommend to use Elm tools or simple multi-platform scripts as much as possible.

  2. There is a very helpful Rust task runner that can auto-install Rust toolchains and tools when needed => users just install it with cargo install cargo-make and when they execute commands like cargo make watch it automatically installs cargo-watch and wasm-pack and run predefined wasm-pack build command. Also there is integrated a simple multi-platform shell language Duckscript.

  3. Notes about your Cargo.toml:

    • Old wasm-bindgen-test version. (The current one is 0.3.10).
    • Sometimes opt-level = "z" compiles to smaller WASM file size (and sometimes not, you have to check).
    • Merge/add below code at the end of the Cargo.toml to optimize it further:
Size optimization in Cargo.toml
[profile.release]
lto = true           # enable advanced / slower LLVM optimizations
opt-level = 'z'      # or `s` for size ; value `3` for speed
codegen-units = 1    # run in a single thread to perform single-thread optimizations

[package.metadata.wasm-pack.profile.release]
wasm-opt = ['-Os']   # config `wasm-opt` (the one of the `binaryen` tools integrated into `wasm-pack`)

I didn’t have too much time to test it more so I hope this quick tips help somehow.
Cheers, M.

3 Likes

Thank you so much for the tips! They are really helpful. I also checked out Seed and it looks amazing! I’m working on a web app project recently and I will definitely give Seed a try.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.