

Discover more from hrbrmstr's Daily Drop
Bonus Drop #33 (2023-11-19): WASM/JavaScript Eats The R/Web World
WebR In Observable; WebR In Node.JS; Yew
Due to time constraints last week there was no WPE again, so everyone gets the Bonus Drop.
This Bonus Drop is also late because of the topic in the first section.
We're going to look at three WASM/JS projects that underscore my assertion that a good chunk of us will end up in WASM land in some way, shape, or form.
WebR In Observable
If you're a new subscriber (there has been a recent trickle of new Drop friends joining the cabal), you may not know my 💙 for WebR, or WASM-ified R.
WebR Version 0.2.2 was recently released and with it came the possibility of finally running WebR in Observable Notebooks, another bit of tech I 💙.
The Observable runtime provides a rich JavaScript library, exquisite plotting tools, and bonkers cool reactivity.
Despite DuckDB (WASM) and arquero being readily available, data wrangling in JavaScript still feels pretty broken if you come from R, Python, or Julia.
We can now use the {tidyverse} in Observable to do proper data manipulation and use that data elsewhere in the notebook. This is a small example in a demo notebook that also contains a few other demonstrations of interop between R and Observable JS.
The runtime is also not limited to the Observable platform. I used my Quartize (GH) browser extension to turn that notebook into a Quarto document. You can see the results in this compiled document.
I suspect there will be an influx of R folks to the Observable platform in the coming weeks/months, and I'll keep working on more examples and helper functions to make life there a bit easier.
WebR in Node.JS
George Stagg dropped a minimal WebR-in-Node.JS repo on us all a couple weeks ago,
Colin Fay has been doing great work making it much easier to deal with with R WASM packages in WebR in the context of Node.JS apps, and Jeroen Ooms has leveled-up R-universe with binary WASM package support.
Yes, that's right, you can use WebR in CLI- and server-based JS land without the need for the end-user to have a working R installation.
This means we finally have a truly easily portable version of R to use pretty much anywhere without having to ask users to deal with a local R installation.
This is huge.
Go forth and build bulky and insecure Electron apps with a Node back-end that uses R!
Make some astonishing CLIs that will let folks see just how great R is!
Colin has you covered on the server-side, and I put together a CLI example that has some batteries includes, such as:
a
package.json
withbin
field, so you cannpm install -g
it and run it as a CLIa
justfile
with sections for setting up local packages and running the tool in dev modehow to take input from the CLI, pass it to R, and use the output from that R code call (in this case, the {stringi} function that generates random lorem ipsum text) in JS land.
I pushed the CLI example to NPM so you should be able to do:
$ npm install -g webr-stringi-node
and use webrsum
without even cloning the repo.
Yew
Not every super spiffy Bonus Drop or regular awesome Drop reader cares about R, so I felt compelled to talk about one other cool WASM project that uses Rust.
Yew (GH) is a modern Rust framework that enables us to create multithreaded front-end web applications using WASM. It's inspired by Elm (I keep meaning to write about Elm) and React, and is designed to be reliable and efficient. Yew features a macro for declaring interactive HTML with Rust expressions, which might feel familiar if you've used JSX in React. It also supports server-side rendering (SSR). I am not yet convinced it is a good thing, given that every site I visit that uses it seems to have that loading "pause" because they aren't popular enough to have sufficient bits in the web server cache to gain the benefits of SSR.
The TL;DR of Yew is that it makes it possible to write front-end code in Rust (vs. JavaScript), a language known for its performance and safety guarantees. This can be a b big plus if you're working on a large single-page application (SPA) or processing lots of data. Some developers have reported performance, stability, and productivity gains when using Yew in large-scale production development.
Yew also supports JavaScript interoperability, which is significant if you're integrating with existing JavaScript code or libraries. And if you're worried about the initial load time of the WASM container (something WebR just massively improved), some developers have found it to be only slightly slower than its JavaScript counterparts.
There's a vibrant community around Yew, with a range of projects and templates available to help you get started. You can find everything from games to personal websites, all built with Rust and Yew. There are also templates for starting a Yew project with various tools like wasm-pack and wasm-bindgen.
To give you a feel for it, the small code snippet below (complete version in this snippet) renders some HTML into the browser via Rust. It's a riff from one of the Yew examples that has the HTML in a separate file that gets included in the build (so it's less ugly than this).
use yew::{Component, Context, Html};
const HTML: &str = "
<meta name='color-scheme' content='dark light'>
<style>
body {
font-family: sans-serif;
width: 60%;
margin: auto;
}
</style>
<h2>Inline HTML with SVG</h2>
<p>
The whole contents of this page is stored as
a constant HTML string in the Rust source code.
The code queries the DOM, creates a new element,
and applies this snippet of HTML to the element's
innerHTML.
</p>
[[[ UGLY SVG CODE TOO BIG FOR SUBSTACK]]]
";
pub struct App;
impl Component for App {
type Message = ();
type Properties = ();
fn create(_ctx: &Context<Self>) -> Self {
Self
}
fn view(&self, _ctx: &Context<Self>) -> Html {
Html::from_html_unchecked(HTML.into())
}
}
fn main() {
yew::Renderer::<App>::new().render();
}
You can check it out at the Yew Playground.
FIN
Despite all the IRL woes happening here and abroad, we do have some exciting new tech to use to build things that can help make the world a little brighter than it was. ☮