Type: Package
Title: Reproducible Code for 'Shiny' Objects
Version: 0.1.0
Description: Provides functionality to extract reactive expressions from a 'shiny' application and convert them into stand-alone R scripts. This enables users to reproduce tables and visualisations outside the interactive UI, facilitating integration into static reports or automated workflows without requiring access to the original application source code.
License: MIT + file LICENSE
URL: https://github.com/AscentSoftware/shinyreprex, https://ascentsoftware.github.io/shinyreprex/
BugReports: https://github.com/AscentSoftware/shinyreprex/issues
Depends: R (≥ 4.3.0)
Imports: S7, constructive, purrr, rlang, styler
Suggests: knitr, rmarkdown, shiny, spelling, testthat (≥ 3.0.0)
Language: en-GB
Encoding: UTF-8
RoxygenNote: 7.3.3
Config/testthat/edition: 3
Config/Needs/website: ascentsoftware/ascentdown
VignetteBuilder: knitr
Collate: 'Repro_S7.R' 'S7_utils.R' 'repro_call_chunk.R' 'call_chunk_function.R' 'call_chunk_generic.R' 'call_chunk_if.R' 'call_chunk_null.R' 'call_chunk_reactive.R' 'call_chunk_reactval.R' 'call_chunk_shiny.R' 'call_chunk_subset.R' 'call_chunk_utils.R' 'repro_chunk.R' 'chunk_call.R' 'chunk_generic.R' 'chunk_reactive.R' 'package.R' 'reprex_reactive.R'
NeedsCompilation: no
Packaged: 2026-03-30 09:01:48 UTC; ashley.baldry
Author: Ashley Baldry [aut, cre]
Maintainer: Ashley Baldry <ashley.baldry@acuityanalytics.com>
Repository: CRAN
Date/Publication: 2026-04-02 08:00:02 UTC

Reproducible Code

Description

An S7 object that holds the code and packages required to re-create a given reactive.

Usage

Repro(code = list(), packages = character(0), prerequisites = list())

Arguments

code

Code chunks found in a given expression

packages

Packages found in the function calls in the code and/or pre-requisites

prerequisites

Code chunks used to generate reactive objects found in the code


Custom S7 Classes

Description

Additional classes to include in S7 to use in repro_code and repro_code_chunk methods:

Reactives

These variables need to be handled in a specific way to extract non-static values stored in reactive calls.

class_reactive

The class capturing shiny::reactive() calls

class_event_cache

The class capturing shiny::bindCache() calls

class_event_reactive

The class capturing shiny::bindEvent() calls

class_bind_reactive

The union of class_event_cache and class_event_reactive

Special Functions

When determining evaluating a chunk, the function name gets attached to the class of the chunk, these are special cases that need to be handled in a non-standard way.

class_call_function

The class capturing anonymous function definitions

class_call_reactive

The class capturing evaluated shiny::reactive() objects

class_call_reactval

The class capturing evaluated shiny::reactiveValues() objects

class_call_if

The class capturing if calls

class_call_null

The class capturing undefined calls, such as pkg::fn

class_call_shiny

The class capturing ignorable shiny function calls such as shiny::req() and shiny::validate()

class_call_subset

The class capturing a subset ($) call


Reactive Variables Definition Check

Description

A helper function to check whether or not the reactive variables to be added to the Repro object already exists. Used to avoid duplicate definitions being added to a script.

Usage

is_new_reactive(new, exisitng)

Arguments

new, exisitng

A named list of reactive variable definitions

Value

A boolean stating whether or not there is at least one reactive definition in new that doesn't exist in existing


Call Checks

Description

A set of helper functions that determine what type of call is being made within an expression.

is_reactive_call checks whether or not the call is evaluating a shiny::reactive variable.

is_reactive_val_call checks whether or not the call is evaluating a shiny::reactiveVal variable.

is_reactive_values_call checks whether or not the call is evaluating an item within a shiny::reactiveValues variable.

is_any_reactive_call checks whether or not the call points to evaluating a reactive, reactiveVal or reactiveValues.

is_variable_call checks whether or not the call point to a variable that is defined within the given module.

is_input_call checks whether or not the call points to evaluate an input value.

is_session_user_data checks whether or not the call points to evaluate an object within session$userData

Usage

is_reactive_call(x, env = rlang::caller_env())

is_reactive_val_call(x, env = rlang::caller_env())

is_reactive_values_call(x, env = rlang::caller_env())

is_any_reactive_call(x, env = rlang::caller_env())

is_variable_call(x, existing_vars = NULL, env = rlang::caller_env())

is_input_call(x)

is_session_user_data(x)

Arguments

x

An R call object

env

The environment the call is being made, by default it is the environment calling the check, but is likely the environment the call is being made i.e. the reactive expression.

existing_vars

A character vector of variable definitions that exist in the Repro object

Value

A boolean value determining whether or not the call check has passed.


Reproduce Code

Description

Construct the code within a given shiny::reactive object to be able to re-create the output outside of a Shiny session.

Usage

reprex_reactive(x)

Arguments

x

shiny::reactive object to make reproducible

Value

A character string, that when printed (using base::cat), displays the script that reproduces the contents of x.

Examples

library(shiny)

ui <- fluidPage(
  h1("Reproducible Code Example"),
  inputPanel(
    sliderInput(
      "min_width",
      "Minimum Petal Width",
      min(iris$Petal.Width),
      max(iris$Petal.Width),
      min(iris$Petal.Width),
      step = 0.1
    ),
    selectInput(
      "summary_fn",
      "Summary Function",
      c("Mean" = "mean", "Median" = "median", "SD" = "sd"),
      selected = "mean"
    )
  ),
  fluidRow(
    column(
      width = 5,
      h2("Table"),
      tableOutput("table")
    ),
    column(
      width = 7,
      h2("Code"),
      verbatimTextOutput("code")
    )
  )
)

server <- function(input, output, session) {
  iris_filt <- reactive({
    iris[with(iris, Petal.Width > input$min_width), ]
  })

  summary_tbl <- reactive({
    aggregate(
      Sepal.Width ~ Species,
      data = iris_filt(),
      FUN = get(input$summary_fn)
    )
  })

  output$table <- renderTable(summary_tbl())
  output$code <- renderText(reprex_reactive(summary_tbl))
}

if (interactive()) {
  shinyApp(ui, server)
}


Reproduce Code Chunk

Description

Evaluate a chunk of code to extract Shiny inputs and reactives, replacing the inputs with the values selected by the user, and the reactives with the code bodies used to generate them.

Usage

repro_chunk(x, repro_code = Repro(), env = rlang::caller_env())

Arguments

x

shiny::reactive() object to make reproducible

repro_code

A Repro object to store calls found in x. By default it is empty, but if x is not the first call within an expression, this will have prior calls and pre-requisites that might be used in x.

env

The environment x is defined in. By default it is the environment of where reprex_reactive is called

Details

Whilst a default is provided to env, it is unlikely that this is the same environment x is defined in. This allows the top-level reprex_reactive call to pass through environments found for calls to other reactives in the chunk.

Value

A Repro object containing all the necessary code and packages to recreate the provided expression when evaluated.