14  Interactive Reporting

Author
Affiliation

Dr Randy Johnson

Hood College

Published

March 5, 2026

Acknowledgements

Most of what we’ll discuss today can be found at quarto.org, the Quarto-Live documentation or shinylive.io. Gemini Code Assist was also active during the development of these materials, and some text was generated with its assistance.

Introduction & The Need for Interactivity

  • Static vs. Interactive:

    • Quarto is excellent for static reports (HTML, PDF, Word)

    • Static documents only show pre-computed results

    • Compute engine can be attached to the document to enable interactivity

  • Enter Shiny:

    • Traditionally, Shiny (in R or Python) creates interactive web apps

    • Quarto natively supports embedding Shiny elements directly into Markdown documents

    • Instead of writing a full standalone app UI, you can write a narrative document and embed interactive widgets (sliders, plots) throughout

Server-Backed Shiny in Quarto

  • When a user interacts with a slider, the browser sends a request to a backend server (running R or Python)

  • The server recalculates the output (e.g. a plot) and sends the image/data back to the browser

Implementation in Quarto

  • To enable this, add server: shiny to the YAML header

Example yaml header

---
title: "My Interactive Report"
format: html
server: shiny
--- 

Example R code chunk

#| panel: sidebar
sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30)

#| panel:
fill plotOutput("distPlot") 
#| context: server
output$distPlot <- renderPlot({
  x    <- faithful[, 2]
  bins <- seq(min(x), max(x), length.out = input$bins + 1)
  hist(x, breaks = bins, col = 'darkgray', border = 'white')
}) 

The Deployment Bottleneck

  • Because it requires a backend to compute, you cannot host this on simple static hosting (like GitHub Pages, Netlify, or standard web servers)

  • You must deploy to a specialized server (e.g. shinyapps.io, Posit Connect, or your own Shiny Server)

  • Cons: Can be expensive, hard to scale if thousands of users visit at once, and requires server maintenance

WebAssembly (Wasm) & Shinylive

  • WebAssembly (Wasm)

    • A binary instruction format that allows code written in languages like C, C++, Rust—and now R and Python—to run natively inside the web browser at near-native speeds

    • Magic: The browser becomes the server!

WebR and Pyodide

  • WebR: A version of the R interpreter compiled to Wasm.

  • Pyodide: A version of the Python interpreter compiled to Wasm.

Shinylive

  • Shinylive bundles your Shiny application, the WebR/Pyodide engine, and the necessary packages into a static bundle

  • When the user opens the webpage, the entire R/Python engine downloads into their browser cache and runs locally on their machine

NoteImportant Note on Extensions (quarto-live vs shinylive):

If you Google this, you will often see tutorials using filters: [shinylive]. That belongs to the older quarto-ext/shinylive extension which only embeds Shiny apps.

Today, we are using the newer, broader r-wasm/quarto-live extension. It allows us to embed Shinylive apps and execute live code cells. Because it injects WebAssembly engines into the document, it requires the special format: live-html in the YAML header.

Serverless Interactivity with quarto-live

  • The easiest way to use Shinylive in Quarto is via the quarto-live extension

  • It allows execution of R and Python code blocks right in the browser

# install quarto-live with
quarto add r-wasm/quarto-live

YAML Example

---
title: "Serverless Report"
format: live-html
engine: knitr # or jupyter for Python
--- 

Using Live Code Blocks

  • Instead of {r}, use {webr} (for R) or {pyodide} (for Python) to create interactive code editors where users can run and modify code on the fly!

Embedding Full Shinylive Apps

You can use the {shinylive-r} or {shinylive-python} code blocks to embed complete, serverless Shiny applications directly in the document.

Deployment

  • Standard Shiny deployment requires a server (cloud service or expensive private servers)

  • Shinylive / Quarto-live Deployment:

    • The output is 100% static HTML, CSS, JavaScript, and Wasm files.

    • Where can you host it? Anywhere.

    • GitHub Pages, Netlify, Amazon, …

Trade-offs

  • Initial Load Time: The first time a user visits, they have to download the Wasm engine - the more complicated the greater the download/load time (anywhere from a few seconds to hanging forever).

  • Data Privacy: Since the compute happens in the user’s browser, you cannot hide your proprietary code or secure database credentials in the Shinylive app. All data sent to the app is pushed to the client.

  • Compute Limits: It relies on the user’s RAM and CPU. Not suitable for massive big-data machine learning jobs.

Summary

  • Use Server-backed Shiny for heavy compute, large datasets, or when code/data must remain private.

  • Use Shinylive/Quarto-live for educational tools, public dashboards, low-cost hosting, and infinite scalability.

Resources

  • Quarto Interactive Documents (Official Docs):

  • Quarto-Live Documentation:

  • Shinylive (R) Official Site:

    • Link: https://shinylive.io/r/

    • Use for: An online playground to test and build serverless R Shiny apps right in your browser.

  • Shinylive (Python) Official Site:

Review Questions

  • What is the primary limitation of standard, static Quarto documents when it comes to data exploration?
  • In a traditional server-backed Shiny application embedded in Quarto, where does the code computation actually happen?
  • What is WebAssembly (Wasm), and why is it described as turning the user’s browser into the server?
  • Describe the “Initial Load Time” trade-off associated with Shinylive. Why does the first visit take longer than subsequent visits?
  • Why is Shinylive/Quarto-live not recommended for applications that require highly sensitive database credentials or massive machine-learning computations?