R build status CRAN status Lifecycle: experimental

The shinymeta R package provides tools for capturing logic in a Shiny app and exposing it as code that can be run outside of Shiny (e.g., from an R console). It also provides tools for bundling both the code and results to the end user.


Install the stable release of shinymeta on CRAN:


Or, install the development version with:


Generating code with shinymeta

In short, shinymeta provides counterparts to Shiny’s reactive building blocks (e.g., reactive() -> metaReactive(), observe() -> metaObserve(), render() -> metaRender()) that have the added ability to capture and expose the logic needed to recreate their current state outside of the Shiny runtime. Once the appropriate logic has been captured by these meta-counterparts and reactive reads (e.g., input$var, var()) have been marked by a special ..() operator, then expandChain() can produce code to replicate the state of a particular meta-counterpart (e.g., output$Summary).


ui <- fluidPage(
  selectInput("var", label = "Choose a variable", choices = names(cars)),

server <- function(input, output) {
  var <- metaReactive({
  output$Summary <- metaRender(renderPrint, {
  output$code <- renderPrint({

shinyApp(ui, server)

For more details, explanation, and overview shinymeta features, see the article on code generation as well as code distribution.

Breaking changes in shinymeta 0.2.0

On August 6, 2019, we introduced a major syntax change into shinymeta, that is not compatible with the previous syntax. If you’re here after watching @jcheng5’s useR2019 talk or reading @zappingseb’s blog post, please be aware that the !! operator has been replaced with a ..() function. See this page for details.

A motivating example

Below is a screen-recording of a Shiny app which allows you to obtain CRAN download statistics for any combination of CRAN packages, look at those downloads using different aggregations, and produce a Rmd-based report with code to reproduce the visualization. This Shiny app is different from most in that it generates R code to reproduce what the user sees in the Shiny app (i.e., notice how the generated report reflects the user’s input).

We hope this example helps illustrate and inspire several reasons why you might want to generate standalone R code that mimics logic in your Shiny app:


Many people projects provided motivation, inspiration, and ideas that have lead to shinymeta. Thanks especially to Adrian Waddell for inspiring the over-overarching metaprogramming approach and Doug Kelkhoff for his work on scriptgloss. Also thanks to Eric Nantz and Xiao Ni for providing feedback and insight on potential applications. We’d also like to acknowledge and highlight other work towards this same goal such as (Eric Hare and Andee Kaplan) and (Vincent Nijs).