Playgrounds with WebR and Quarto


March 16, 2023

A screenshot of a webpage that has an embedded R code block. Some text asks the user to adjust the code and then click a button that says 'run code'. A shocked Pikachu appears in the corner.


WebR lets you run R in the browser(!). Now you can make WebR chunks in Quarto that render to editable, executable blocks(!).

Sliding into tedium

I wrote recently a simple introduction to how R parses code. I provided a function that I said the reader could go away and run themselves.

As in… copy-paste it into an instance of R running on their machine. Gross.

Wouldn’t it be better if people could just tinker with the code right there in the post? This kind of ‘playground’ could be great for explaining concepts and teaching.1

I seesaw a solution

WebR lets you run R in the browser. Read that again! This is a landmark piece of work from George Stagg and Lionel Henry.

I won’t go into technicals and limitations here. For more information, see:

Crucially for my needs, you can now run WebR chunks in a Quarto document, thanks to James J Balamuta. This renders interactive blocks of R code that the reader can adjust and execute with button-click:

Animated gif showing a code block with R code inside that sets the value of 'x' to 'world' then pastes it together with the string 'hello'. A 'run code' button is clicked and the string 'hello world' is printed. The word 'hello' is then changed to 'ahoy' and the code is re-run and the printout changes to 'ahoy world'.

Beware: this is a gif, not an embedded demo!

Check out James’s coatless/quarto-webr GitHub repo for the source. There’s also a live demo and its source.

Swinging into action

To have a go yourself, do follow the setup steps in James’s quarto-webr README and look at the source of his demo.

Ultimately you can:

  1. Install the extension to your project folder by running quarto add coatless/quarto-webr in the terminal
  2. Set filter: webr in the YAML of your qmd file2
  3. Write code chunks in the qmd using the {webr} engine

This made it straightforward to prepare a little Quarto doc with chunks powered by the ‘webr’ engine, which I deployed to the web via Netlify.3

You can visit that live page or see the underlying source on GitHub.4

So now you can tinker with the example I gave in the original blogpost about parsing R code. Unfortunately I can’t add this directly to the post, since this blog is not made with Quarto.

A blog-platform merry-go-round

I’ve written this quick demo and post because I was excited about what George & Lionel and James have put together. There’s so many system-independent applications of this approach that could help with teaching and learning, or explaining simple ideas in a blog post.

In fact, this blog may eventually switch from {blogdown} to Quarto to take advantage of WebR. It’ll be a pain to convert old posts, but luckily I already missed the earlier {blogdown}-to-{distill} bandwagon, lol.5


Session info
Last rendered: 2023-07-21 18:39:33 BST
R version 4.3.1 (2023-06-16)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.2.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRblas.0.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0

[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Europe/London
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
 [1] htmlwidgets_1.6.2 compiler_4.3.1    fastmap_1.1.1     cli_3.6.1        
 [5] tools_4.3.1       htmltools_0.5.5   rstudioapi_0.15.0 yaml_2.3.7       
 [9] rmarkdown_2.23    knitr_1.43.1      jsonlite_1.8.7    xfun_0.39        
[13] digest_0.6.33     rlang_1.1.1       evaluate_0.21    


  1. A nice example of this in a teaching context is W3 Schools, who have a ‘Try It Yourself’ space that lets you take code from the lessons and tinker with it yourself in the browser.↩︎

  2. Set also engine: knitr in the YAML to use {knitr} instead of Jupyter to handle the conversion. You can add format: html to ensure that the output is rendered to HTML.↩︎

  3. Self-deployment and Netlify are viable for now, GitHub Pages is coming later. Netlify is how this blog is deployed.↩︎

  4. Originally I tried to embed the Quarto demo in an iframe, but WebR failed to load inside it when the blog was rendered. That’s interesting.↩︎

  5. But came close when I thought I’d found a system for making individual posts reproducible.↩︎