Resources

webR 0.2: R Packages and Shiny for WebAssembly | George Stagg | Posit

WebR makes it possible to run R code in the browser without the need for an R server to execute the code: the R interpreter runs directly on the user’s machine. But just running R isn't enough, you need the R packages you use every day too. webR 0.2.0 makes many new packages available (10,324 packages - about 51% of CRAN!) and it's now possible to run Shiny apps under webR, entirely client side. George Stagg shares how to load packages with webR, know what ones are available, and get started running Shiny apps in the web browser. There’s a demo webR Shiny app too! 00:15 Loading R packages with webR 01:50 Wasm system libraries available for use with webR 05:30 Tidyverse, tidymodels, geospatial data, and database packages available 08:00 Shiny and httpuv: running Shiny apps under webR 11:05 Example Shiny app running in the web browser 12:05 Links with where to learn more Shiny webR demo app: https://shinylive.io/r/examples/ Website: https://docs.r-wasm.org/ webR REPL example: https://webr.r-wasm.org/latest/ Demo webR Shiny app in this video: https://shiny-standalone-webr-demo.netlify.app/ Source: https://github.com/georgestagg/shiny-standalone-webr-demo/ See the overview of what's new in webR 0.2.0: https://youtu.be/Mpq9a6yMl_w

image: thumbnail.jpg

Transcript#

This transcript was generated automatically and may contain errors.

Hello, in this video I'm going to be talking about WebR 0.2.0 and in particular R packages for WebAssembly. So WebR supports loading R packages. They have to first be available on the virtual file system, but once they're there they can be loaded. So there's a few ways to ensure that those packages are there. They can be manually copied to the virtual file system location userlib R library, but there's also a helper function provided by WebR that will install R packages to that location for you. This helper function also is connected to a binary repository that contains R packages built for WebAssembly. So if you ask for a package that exists in that repository, it'll go and download it, extract the files and put them on the virtual file system for you.

Challenges compiling packages for WebAssembly

There is issues when it comes to converting R packages to run on WebAssembly. The biggest issue is probably that R packages with compiled code need to have that code recompiled so that it can run under WebAssembly. And that includes not only the code that exists inside an R package, but also any system libraries that that code depends on. So if you have some C code in an R package that uses libexml2, for example, to parse some XML files, that system library, that XML system library will also have to be converted into WebAssembly and provided so that that package can run under WebR. So we've done some work in WebR 0.2.0 to increase the number of system libraries available for use with WebR. And the way we do this is that we have certain recipes that exist in the WebR source repository. And if you ask for these packages to be built, there's a command you can run to build them all. It will go away and build all these packages one by one for WebAssembly. And once those packages are built for WebAssembly, R packages can be linked to use them to include that code in those R packages.

So there's a selection of new libraries here. There's various graphics libraries that are used in the previous videos when I talked about the Cairo bitmap graphics. There's text rendering and graphics libraries. There's some various utility libraries. There's sqlite3 for databases. And there's also some geospatial and computational geometry packages like geos, gdal, and proj. And they are used to enable some extra geospatial packages in the latest version of WebR.

Package availability: 51% of CRAN

By including these system libraries, we've been able to expand the number of R packages that are supported by WebR. And those R packages are hosted on a binary repository at that URL there. And this is the repository that's automatically used by the WebR install command if you do ask for an R package in WebR. So in the previous release, by the end of that release cycle, we had about 219 packages available for use. Now we have more. We have 10,324, which is about 51% of CRAN. And that's how many packages are available in that binary repo now.

We have 10,324, which is about 51% of CRAN. And that's how many packages are available in that binary repo now.

I should say that we haven't tested all of these packages. What available here means is that a package is able to be compiled by the inscription compiler for WebAssembly, so that R package can be compiled, as well as all the packages that it depends on. So if an R package depends on some other R package, if it's available in WebR, it means that all of that dependency chain has been resolved and all of those packages have been compiled for WebAssembly.

So because there are quite a few packages available now, you can use built-in R tools to list those packages. I think the function is available.packages to list all of those. But it might be a bit tricky to run through all that data, particularly if you just want to know if a single package works or not. So one of the things we've done is we've updated the repository so that the index page, if you were to visit that repository in a web browser, the index page that you see after a loading period looks like this. And it tells you how many packages are available, and it gives you a list that you can search through. So for example, if you wanted to know if ggplot's available, you could just type ggplot2 in the box there, and you can see, okay, package ggplot2 is available, and all of its dependencies are also available. So I can use that package in WebR. So this is a really nice, useful little tool just to see which packages are now available for use in WebR.

Examples: tidyverse, tidymodels, geospatial, and databases

Some examples of packages that are now available, tidyverse and tidymodels are both available. So if I run that code, it will go and download those packages. There they are. Not all of the tidyverse packages are available, I should admit. There are some that can't easily be used in WebAssembly because they need to connect to the network, and direct network access is one of the things that's restricted in the WebAssembly environment. But the core tidyverse packages are there and can be attached, and the same with tidymodels. The tidymodels packages are available, and they can all be attached. So you can run your tidymodels code in WebR, and you can run your core tidyverse code in WebR.

Geospatial packages are available. So in particular, that includes the sf package for simple features. So if I run this piece of code again, it'll go and download those packages and then run this small piece of code that's going to plot a map for us, projected onto a certain type of map projection. So there's some computational geometry going on there, and then all of those state lines are plotted with ggplot here in this example. So there are various geospatial data packages available now to use in WebR.

And there's also database packages. So here is an example of the dbi package being used with the rsqlite package. Database systems on a server somewhere connected over the network won't work, again because network connections are one of the things in WebAssembly that's restricted. But in-memory databases like sqlite is available. So here's an example that takes some data and puts it into an sqlite database. And then we have some SQL code here that we can use to query that data. So if you're a user who prefers to use R with dbi to run SQL code, you can do that. You can change the code and get immediate results in WebR. You can see I'm not a SQL programmer as you can see by that previous example, but it does work. You're able to run your SQL code directly there.

Again, sqlite's probably the only database that is well supported here, just because many other databases will require network connections.

Shiny for WebAssembly with httpuv shimming

And finally, the last thing I want to talk about with R packages is Shiny and httpuv, which is one of the support packages that Shiny uses. So the httpuv package, again, is based on network connections. It's a server that can listen for HTTP and WebSocket traffic and then respond to those requests. So a package shim has been created for WebR, which is available on the RWASM organization, if you want to read the source code for that. And what that is, is it's a package that acts like httpuv, but is re-implemented to be used with WebR. And in particular, what it's doing is taking advantage of a JavaScript feature known as service workers. And service workers are nice because they can act as network proxies. So normally when that traffic that httpuv would handle over the network is instead being handled entirely client-side, inside a JavaScript service worker instead. And that service worker acts as our network server when really it's all running client-side.

With this shim, Shiny apps are able to run under WebR, and in particular, they can run entirely client-side. So the way this works is that the R Shiny server software thinks it's talking to httpuv through its normal R package API. And at the other side, we have the Shiny web client that the user is interacting with. That thinks it's talking over the network to the Shiny server, but instead that is being intercepted, as I say, by the JavaScript service worker. And then that proxy in the middle between the Shiny server and the Shiny client converts those network requests, captures them, converts them, and sends them to WebR. And WebR works with httpuv to handle those messages. And the responses from Shiny, again, are sent back to the client at the front end through that network proxy, through that service worker. So through this package shimming process, we're able to run Shiny apps entirely within the browser with both the front end and the back end server, all running inside a JavaScript worker.

This is a similar scheme, by the way, to how shinylive for Python works. It's not exactly the same, but it is a similar scheme. And so we're hoping that in the near future, we'll be able to integrate this kind of thing directly into shinylive to create a shinylive for R, which will take the complication of deploying apps like this away so that the general user will be able to use shinylive to deploy R Shiny apps in this way, rather than having to learn the intricacies of how to use a JavaScript service worker or deploy their own application in this way.

Demo: Shiny running entirely client-side

I do have an example. So this is a Shiny app running directly in the web browser. And you can confirm for yourself that this really is running entirely client-side because that output at the bottom of the screen is the output from an R console running Shiny server. So that output is directly from the Shiny server itself. And I could disconnect the network, I could turn the internet off, and this would still work.

And I could disconnect the network, I could turn the internet off, and this would still work.

The code for that demo is available on GitHub. So if you are a JavaScript developer and you know about web workers and service workers, you can read a little more about how this works in a bit more detail on that GitHub page. And it also talks about some of the requirements for deployment, particularly when it comes to setting special HTTP headers for cross-origin isolation. This is something that's required to get WebR to run in this environment.

So that's everything I want to talk about R packages. So do visit the REPL app at the URL at the top of the screen there and try this out. Load some packages and see for yourself which ones work and which ones don't. And if you do want to create your own WebR apps, it's available on npm or via CDN. And the documentation is at that URL there, which is well worth looking through if you are wanting to integrate WebR into your own web applications. If you do do any interesting projects with WebR and want to share them, please do feel free to email me. My email is shown on the screen there and I'd love to see what kind of projects you create with WebR. Thank you very much.