Provides tools for analyzing and understanding the file contents of large 'shiny' application directories. The package extracts key information about render functions, reactive functions, and their inputs from app files, organizing them into structured data frames for easy reference. This streamlines the onboarding process for new contributors and helps identify areas for optimization in complex 'shiny' codebases with multiple files and sourcing chains.
The {shinyfa} package is designed to help Shiny developers analyze and understand the file contents of large Shiny app directories.
Large Shiny applications often contain numerous files that define both dynamic UI and server components, sometimes linked together in complex sourcing chains (though this is less common in Shiny apps structured with modules). For new contributors—such as consultants joining a project—it can take considerable time to onboard, navigate the codebase, and identify areas for optimization.
This in-progress package aims to streamline that process by extracting key information from a Shiny app directory. It identifies specific render functions, reactive functions, and their inputs, organizing them into a structured data.frame for easy reference.
The fa in shinyfa stands for file analysis.
Install from CRAN:
install.packages("shinyfa")
Or install the development version from GitHub:
# Install from GitHub
devtools::install_github("dalyanalytics/shinyfa")
# Or using pak
pak::pak("dalyanalytics/shinyfa")
Analyze a typical Shiny app structure:
library(shinyfa)
library(dplyr)
# Analyze server files in your Shiny app
server_files <- list.files("my_shiny_app/server",
pattern = "\\.R$",
full.names = TRUE,
recursive = TRUE)
file_analysis <- data.frame()
for (file in server_files) {
shiny_analysis <- analyze_shiny_reactivity(file_path = file)
if (is.null(shiny_analysis)) next
shiny_analysis$file_name <- basename(file)
file_analysis <- bind_rows(file_analysis, shiny_analysis)
}
# View the analysis results
print(file_analysis)
#> type name inputs output file_name
#> 1 render plotSales c("dateRange", "product") plotOutput sales_module.R
#> 2 reactive filteredData c("selectedRegion") NULL data_processing.R
#> 3 observe updateFilters c("input$reset") NULL ui_helpers.R
#> 4 render tableSummary c("filteredData") tableOutput summary_module.R
#> 5 observeEvent downloadHandler c("input$download") NULL download_handlers.R
# Find all reactive expressions that depend on a specific input
file_analysis %>%
filter(type == "reactive",
grepl("dateRange", inputs)) %>%
select(name, file_name)
# Identify potentially unused render functions
file_analysis %>%
filter(type == "render",
is.na(output) | output == "")
.R filesContributions are welcomed!
MIT © Jasmine Daly / shinyfa authors