Skip to contents

Overview

The livelink package revolutionizes how you share R code and Shiny applications by creating shareable URLs that run entirely in the browser. No server setup, no complex deployments—just instant, executable links that work anywhere with a modern web browser.

This package supports two powerful platforms:

  • WebR: Execute R code directly in the browser using webR, a port of R to WebAssembly
  • Shinylive: Run R and Python Shiny applications without requiring a server using Shinylive

The magic happens through intelligent compression and encoding of your code into URL fragments, making sharing as simple as copying and pasting a link.

Traditional code sharing often involves complex setups:

  • Email attachments that may not run on different systems
  • GitHub repositories requiring users to clone and set up environments
  • Server deployments for Shiny apps with hosting costs and maintenance

With livelink, sharing becomes effortless:

  • Instant Access: Recipients click a link and immediately see running code
  • No Dependencies: Works in any modern browser without additional software
  • Collaborative: Share prototypes and get feedback quickly
  • Reproducible: Links preserve exact code state and dependencies

Quick Start

WebR links allow you to share R code that executes directly in the browser. This is perfect for data analysis scripts, visualizations, and educational examples.

# Simple data analysis example
code <- "
# Load and explore the mtcars dataset
data(mtcars)
cat('Dataset dimensions:', dim(mtcars), '\\n')
cat('Variables:', names(mtcars), '\\n\\n')

# Create a scatter plot
plot(mtcars$mpg, mtcars$wt, 
     main = 'Fuel Efficiency vs Weight',
     xlab = 'Miles per Gallon (MPG)', 
     ylab = 'Weight (1000 lbs)',
     col = 'steelblue', 
     pch = 16)

# Add a trend line
abline(lm(wt ~ mpg, data = mtcars), col = 'red', lwd = 2)
"

# Create the link with autorun enabled
link <- webr_repl_link(code, autorun = TRUE)
print(link)
#> 
#> ── WebR Link ──
#> 
#> <https://webr.r-wasm.org/latest/#code=eJxVkM1O7DAMhV%2FlKPdK7UjVneEuWFSaBeJvAxJiAQuCkNsYGil1q8RlBiF4dhSmDJBF4tjfObJ992qEeja1SW30o%2F67NpUZSTtTm2U39LzccPMwJY7LH4DyVk1trPzBxUAOJA68HcMQGdoxem0pJjhSSqxWclDukgsrLWlZnOxqcL5nSX6QVBdV%2Fn1xFQprpfjibyh6agJ%2FYrnl9Buc2dzScWRSBiG1pMoRYxjUSr5nzd9%2BfKowxxutYAX59OQFaxRnEwecPj761rO0L3hOuGX%2F1GlRzeQ2UJPJSx84YeSIcwphEJSXV%2BeLYu%2F4MnM7OcqD1WqF0KTF3qkdQgaSMocmTPytHdsOaxwczmMdOQeCRhaH4IWtUJPfMvTlRvGOz6HyqrHGfjezfWRXVAgbhzX%2BL6yYytCkQ5zE1Bonfrv%2FANHRqGM%3D&jza>
#> 
#> File: 'script.R' → '/home/web_user/script.R'
#> Version: "latest"
#> Autorun: TRUE

The autorun = TRUE parameter means the code will execute automatically when someone opens the link, immediately showing the results. This is excellent for demonstrations but should be used thoughtfully for educational content where you might want students to run code step-by-step.

Shinylive links create fully interactive web applications from Shiny code. These apps run entirely in the browser using WebAssembly, providing near-native performance without server costs.

# Interactive data exploration app
app_code <- '
library(shiny)
library(ggplot2)

ui <- fluidPage(
  titlePanel("Interactive mtcars Explorer"),
  
  sidebarLayout(
    sidebarPanel(
      selectInput("x_var", "X Variable:", 
                  choices = names(mtcars),
                  selected = "mpg"),
      selectInput("y_var", "Y Variable:",
                  choices = names(mtcars), 
                  selected = "wt"),
      selectInput("color_var", "Color by:",
                  choices = c("None", names(mtcars)),
                  selected = "cyl"),
      sliderInput("point_size", "Point Size:",
                  min = 1, max = 5, value = 3)
    ),
    
    mainPanel(
      plotOutput("scatter_plot"),
      verbatimTextOutput("correlation")
    )
  )
)

server <- function(input, output) {
  output$scatter_plot <- renderPlot({
    p <- ggplot(mtcars, aes_string(x = input$x_var, y = input$y_var)) +
      geom_point(size = input$point_size) +
      theme_minimal() +
      labs(title = paste("Relationship between", input$x_var, "and", input$y_var))
    
    if (input$color_var != "None") {
      p <- p + aes_string(color = input$color_var)
    }
    
    p
  })
  
  output$correlation <- renderText({
    cor_val <- cor(mtcars[[input$x_var]], mtcars[[input$y_var]])
    paste("Correlation coefficient:", round(cor_val, 3))
  })
}

shinyApp(ui = ui, server = server)
'

# Create app link for direct access
link <- shinylive_r_link(app_code, mode = "app")
print(link)
#> 
#> ── Shinylive R App ──
#> 
#> <https://shinylive.io/r/app/#code=NobwRAdghgtgpmAXGKAHVA6ASmANGAYwHsIAXOMpMAHQgBsBLAIwCcoWBPACgGcALBhA4BKWo1btuAcymo6RUgCZREWgFcGAAgA8AWk0AzOhoAmABShS4XWps2kGpOnAsQ4dG2ACSZOGwIOAG5wmjCkBOw8mgCiAB5yRCx+1GDCuLaaGTwMJnBM7AAyUBxEaqQ2EHZ22bn5LK7uFVVVPO5wAT6oZZ6xAPqB7Cm4mWAAGpoAauwMUEzOiEOZlc0rq3YEfEQMBHBRALya0PA8XGERLDxpGWs3mq3OAXAmmgcpMKhSKVfLzfftpJ1uikOP1BngRgBNSbTWbzIbXW6rDZbHb7Q6wXancKRNJLRE3P6PZ6vMAAd1IX3SPxabQ6EC65RSxHkLFBLEWKQAwkQWZomBwFngEfiqsjtrsXpoCJ4AHIkOCLI6Ys4474i1aE8jEkYEDh0SnCu6MXIsQGMsCoLZkXrZABeCvBKTMVtImgAygx7YKqeqVjBBJKAIzDGBQWKSgCswwGxhCBwAzCpmmqqgjQ4IGh5DQlSAB5MoMzw8CKkcisnMG6l2YIsfIOGAAFTgsTzBaBhESSToUAcJC+CKTmhUKlorRYNZ0+gMaggAQYJC4ggZw1KpAZwk0IAyq4ZABJiz2y70c5PNEkICazPJylvqahTzIc1jzjxhlBdjbSCxBFIuOGDkuZS7n0AwsMMHCSoBpC7iCoHCBuADUhpWEQMDHi6vCenGmhQbulqCKQNpYYhhqkHwcDwL0-oQAwoYeCRVaaN2TAnA4TjYagUA8OQnhYO4PbzhA-AMPeTBwKQpJwBQiy4SB7DDCkUAXjJ9JAbB7DwQiCIMAYmiLqp0HMokbKaAAhCScpuF8m7Zqe94IZo748J+34QL+RksJBBm7h5bKDnYAC+Wl3hkAWDtubaGZ2-G9pUehnhQJpNi2XC3s0xCsjGp4Zc+kTAMAslsgAukVIbYhc+W4epLAlf5micdx1hctF3axVKRBwAYBjbAwFCkN6Z6lBeXAZaCdDDImg5hbQQWqEJAhCAAgugXAaJKGjDGOE4HFtfgqHgYCkBwqAIMg5AtmAAVFUAA>
#> 
#> Files (1):
#> 'app.R'
#> 
#> Engine: "R"
#> Mode: "app"

The mode = "app" parameter creates a clean interface showing only the running application, perfect for end users. Use mode = "editor" when you want to show both the code and the running app, which is ideal for educational contexts or code sharing.

WebR links follow a specific pattern:

https://webr.r-wasm.org/[version]/?mode='[components]'#code=[encoded_data]&[flags]
  • Version: Specifies WebR version (latest, v0.5.4, etc.)
  • Mode: Controls interface components (editor, plot, files, terminal)
  • Encoded Data: Your compressed and base64-encoded files
  • Flags: Encoding options (j for JSON, m for MsgPack, z for compression, u for uncompressed, a for autorun all files)

Shinylive links have a different format:

https://shinylive.io/[engine]/[mode]/#h=[header]&code=[encoded_data]
  • Engine: Language (r for R, py for Python)
  • Mode: Display type (editor for development, app for production)
  • Header: Optional shinylive playground header display (1 or 0)
  • Encoded Data: LZ-string compressed application files

Interface Customization

WebR Interface Components

WebR offers granular control over which interface components are visible.

Component Descriptions:

  • Editor: Code editing interface with syntax highlighting
  • Plot: Graphics output panel for visualizations
  • Files: File browser for multi-file projects
  • Terminal: R console for interactive commands
# Show only the editor and plot for focused analysis
analysis_link <- webr_repl_link(code, mode = c("editor", "plot"))

# Show all components for full development environment
full_link <- webr_repl_link(code, mode = c("editor", "plot", "files", "terminal"))

# Use string format for convenience
focused_link <- webr_repl_link(code, mode = "editor-plot")

# Default behavior (NULL) shows all components
default_link <- webr_repl_link(code)

Shinylive Display Modes

Shinylive offers two primary modes optimized for different use cases. The first is the editor mode, which is great for teaching and code exploration, showing both the source code and the running application. The second is the app mode, which provides a clean interface for end users, displaying only the running application. You can also remove the header for embedded applications, which is useful when integrating into other web pages.

# Editor mode: Shows both the source code and running application
editor_link <- shinylive_r_link(app_code, mode = "editor")

# App mode: Shows only the running application
app_link <- shinylive_r_link(app_code, mode = "app")

# Remove header for embedded applications
embedded_link <- shinylive_r_link(app_code, mode = "app", header = FALSE)

Version Management

WebR Versions

Different WebR versions offer varying features and package availability:

# Use latest version for newest features (default)
webr_repl_link(code, version = "latest")
#> 
#> ── WebR Link ──
#> 
#> <https://webr.r-wasm.org/latest/#code=eJxVkM1OwzAQhF9lFZCSShFtOXCoxAHx0wuVEAc4EIQ28baxZDuRvSWtEDw769YtNIf475vxeN6%2BMoeWslkWGq97vnjOyqxHbmVn3HaWxgPVH%2BtAfvwPYNqwAJU7g8cOFaBTQJvedJ6AWwLLDfoAChkDceXipNhvjirXIBf53f4MlLbkgu5cmOVlXB24EvKqcvmBf0GvsTa0w2LkcAomNka69YRMgBBEyeRBgkmI%2BE%2Bac9uvSkjzgUuoHMTPonZwDfnDmgzcL5e60eSaLXwGeCW9ajkvE7kxWEdyoSUS9HLJHI3pHBSLp%2FkoPzpuE7eXQzGdTCZg6jA6OjWdiUBgIlObNf1p%2B6aVk%2BlVetaNkqKBPUnZRjuqnPQhY2FsMTD8wO5RsWpRHbtJ9p6UGJtByeJSDLPv918eIaLr&jz>
#> 
#> File: 'script.R' → '/home/web_user/script.R'
#> Version: "latest"
#> Autorun: FALSE

# Pin to specific version for reproducibility
webr_repl_link(code, version = "v0.5.4")
#> 
#> ── WebR Link ──
#> 
#> <https://webr.r-wasm.org/v0.5.4/#code=eJxVkM1OwzAQhF9lFZCSShFtOXCoxAHx0wuVEAc4EIQ28baxZDuRvSWtEDw769YtNIf475vxeN6%2BMoeWslkWGq97vnjOyqxHbmVn3HaWxgPVH%2BtAfvwPYNqwAJU7g8cOFaBTQJvedJ6AWwLLDfoAChkDceXipNhvjirXIBf53f4MlLbkgu5cmOVlXB24EvKqcvmBf0GvsTa0w2LkcAomNka69YRMgBBEyeRBgkmI%2BE%2Bac9uvSkjzgUuoHMTPonZwDfnDmgzcL5e60eSaLXwGeCW9ajkvE7kxWEdyoSUS9HLJHI3pHBSLp%2FkoPzpuE7eXQzGdTCZg6jA6OjWdiUBgIlObNf1p%2B6aVk%2BlVetaNkqKBPUnZRjuqnPQhY2FsMTD8wO5RsWpRHbtJ9p6UGJtByeJSDLPv918eIaLr&jz>
#> 
#> File: 'script.R' → '/home/web_user/script.R'
#> Version: "v0.5.4"
#> Autorun: FALSE

# Set global base URL for custom WebR deployments
set_webr_base_url("https://my-institution.edu/webr/")
#> WebR base URL set to: <https://my-institution.edu/webr/>
webr_repl_link(code)  # Will use custom URL
#> 
#> ── WebR Link ──
#> 
#> <https://my-institution.edu/webr/#code=eJxVkM1OwzAQhF9lFZCSShFtOXCoxAHx0wuVEAc4EIQ28baxZDuRvSWtEDw769YtNIf475vxeN6%2BMoeWslkWGq97vnjOyqxHbmVn3HaWxgPVH%2BtAfvwPYNqwAJU7g8cOFaBTQJvedJ6AWwLLDfoAChkDceXipNhvjirXIBf53f4MlLbkgu5cmOVlXB24EvKqcvmBf0GvsTa0w2LkcAomNka69YRMgBBEyeRBgkmI%2BE%2Bac9uvSkjzgUuoHMTPonZwDfnDmgzcL5e60eSaLXwGeCW9ajkvE7kxWEdyoSUS9HLJHI3pHBSLp%2FkoPzpuE7eXQzGdTCZg6jA6OjWdiUBgIlObNf1p%2B6aVk%2BlVetaNkqKBPUnZRjuqnPQhY2FsMTD8wO5RsWpRHbtJ9p6UGJtByeJSDLPv918eIaLr&jz>
#> 
#> File: 'script.R' → '/home/web_user/script.R'
#> Version: "latest"
#> Autorun: FALSE

# Reset to default
set_webr_base_url(NULL)
#> WebR base URL reset to default

Version Considerations:

  • Latest: Access to newest features but may change over time
  • Specific versions: Guaranteed reproducibility but may lack newer features
  • Custom deployments: Useful for institutions with specific requirements

Important

You must use WebR version 0.5.4 or later to ensure compatibility with the latest features and packages.

Common Workflows

Teaching and Education

# Step 1: Create exercise with placeholders
exercise_code <- "
# Exercise: Data Summary
# Complete the following analysis of the iris dataset

# TODO: Load the iris dataset
data <- # YOUR CODE HERE

# TODO: Calculate mean sepal length
mean_sepal_length <- # YOUR CODE HERE

# TODO: Create a histogram of petal widths
# YOUR CODE HERE

cat('Mean sepal length:', mean_sepal_length)
"

# Step 2: Create corresponding solution
solution_code <- "
# Solution: Data Summary
data <- iris

mean_sepal_length <- mean(iris$Sepal.Length)

hist(iris$Petal.Width, 
     main = 'Distribution of Petal Widths',
     xlab = 'Petal Width (cm)',
     col = 'lightblue')

cat('Mean sepal length:', mean_sepal_length)
"

# Step 3: Generate exercise pair
links <- webr_repl_exercise(exercise_code, solution_code, "iris_basics")

# Share exercise with students
student_link <- repl_urls(links$exercise)

# Keep solution for grading
instructor_link <- repl_urls(links$solution)

Collaborative Development

# Share work-in-progress for feedback
prototype_code <- "
# Prototype: Segmentation analysis
# TODO: Optimize clustering algorithm

library(cluster)
data(iris)

# Current approach - needs improvement
clusters <- kmeans(iris[,1:4], centers = 3)
plot(iris$Sepal.Length, iris$Sepal.Width, 
     col = clusters$cluster,
     main = 'Customer Segments (Prototype)')

# Questions for collaborators:
# 1. Should we use different clustering method?
# 2. How to determine optimal number of clusters?
# 3. Which variables are most important?
"

collaboration_link <- webr_repl_link(
  prototype_code, 
  filename = "clustering_prototype.R",
  autorun = FALSE)  # Let collaborators run manually

Common Issues

Browser Compatibility

WebR and Shinylive require modern browsers with WebAssembly support:

  • Supported: Chrome 57+, Firefox 52+, Safari 11+, Edge 79+
  • Not supported: Internet Explorer, very old mobile browsers
  • Performance: Desktop browsers generally perform better than mobile

Network Requirements

Links require internet access to load WebR/Shinylive infrastructure, but run locally afterward:

  • Initial load: Downloads WebR runtime (~10-50 MB depending on packages)
  • Subsequent usage: Runs offline in browser cache
  • Package installation: Requires internet for additional R packages

Next Steps

Now that you understand the basics, explore specific workflows:

  • WebR Links: Learn more about R code sharing with advanced multi-file projects, batch processing, and educational tools
  • Shinylive Links: Master Shiny application sharing for both R and Python, including complex multi-file apps
  • Decoding Links: Learn to extract files from existing links, preview contents, and batch process multiple URLs

Each vignette builds on these fundamentals while providing specialized knowledge for specific use cases. The combination of these tools makes livelink a comprehensive solution for modern, browser-based code sharing and collaboration.