Composable Shiny apps

homeblogmastodonblueskythingiverse



Update April 2016: RStudio now has an official way to write composable shiny "modules".



Shiny is a library for writing web applications in R. If you use R, I highly recommend it, it's very clever. If you haven't used R and Shiny, this blog post is going to be pretty incomprehensible.

I wanted a way to compose Shiny apps. I haven't found an official way to do this, so this post details my solution. Maybe some day the clever people at RStudio will release an official way that makes this all moot.


You may want to review the tutorial on the various ways a Shiny app may be constructed and run. I will be constructing Shiny apps using the shinyApp function. This can either be done interactively, or from a file "app.R" in a Shiny app directory. Working interactively, an app is launched when it is print()ed, similar to ggplot. So, working interactively, calling a function to create a shiny app will launch it immediately (unless you save it to a variable). Only in R!

You may also want to review how reactive expressions in Shiny work. Recall that it is the job of the server function in a Shiny app to create all the reactive expressions



My code can be found in my Varistran package, in particular the file shiny_util.R.

What I call a "composable Shiny app" is a function in R returning a Shiny app object (so it can be used in the normal ways), but with that app object having some extra fields, $component_ui containing the UI part of the app and $component_server containing the server function.

varistran::shiny_plot is an example of a composable Shiny app. Such a function constructs ui and server and then calls varistran::composable_shiny_app(ui,server) to create the app.

Considerations when writing a composable Shiny app:

Example

This is all a bit confusing. Reading over the varistran::shiny_plot function should give you a better idea of how it all fits together. You will note in this function:



Example usage:

install.packages(c("devtools", "shiny"))
devtools::install_github("MonashBioinformaticsPlatform/varistran")

library(shiny)

plot_app <- varistran::shiny_plot(
    function(env) {
        plot((1:10)**env$input$power)
    },
    prefix="myplot"
)

ui <- fluidPage(
    titlePanel("Composable app demo"),
    numericInput("power", "Power", 2),
    plot_app$component_ui
)

server <- function(env) {
    plot_app$component_server(env)
}

varistran::composable_shiny_app(ui, server)

Here is the result.

The plot component is able to react to changes from outside, namely the value of input$power.




[æ]