Here are some of the best tips, tricks, and takeaways for R users from this year’s rstudio::global(2021) virtual conference:

Speed up your R code

The new xrprof package builds on code profiling (performance measuring) offered by base R’s Rprof() with these added features:

  • It can run on a remote server, not just locally, allowing you to see what’s happening in your production environment;
  • It can see bottlenecks in C/C++ code, not just R code — especially useful for R package developers using C or C++.

And, it’s a drop-in replacement for the ecosystem of Rprof() add-on tools, said author Aaron Jacobs, senior data scientist at Crescendo. This project was funded in part by the R Consortium.

Customize your R data visualizations

The thematic package lets you customize plot defaults for ggplot2, lattice, and base R graphics. It works within RStudio, R Markdown documents, and Shiny apps. thematic dataviz code might look something like this:

thematic_on(bg = "#222222", fg = "white", accent = "#0CE3AC", font = "Oxanium")

before running a plot. The package includes support for Google fonts.

Improve your R Markdown docs & Shiny apps

Customize design

The bslib package aims to make it easier to create custom themes for Shiny apps and R Markdown documents. It should be on CRAN soon, but meanwhile it’s available to install via remotes::install_github("rstudio/bslib"), according to RStudio’s Thomas Mock. This is a successor to the older bootstraplib package. 

There are a number of other packages that can help you create more compelling Shiny user interfaces. At a pre-conference workshop, Dominik Krzemiński with the Shiny consulting firm Appsilon shared some of his favorites:

ShinyJS – generate JavaScript UI actions such as showing and hiding components, but with R code
ShinyWidgets – access additional input widgets beyond what’s built into Shiny
ShinyCSSLoaders – add animations while data loads or plots are rendering
bs4Dash – build a version of Shiny dashboards using Bootstrap version 4
shinyMobile – create mobile and desktop Shiny apps using Framework7 as the underpinning
shiny.semantic – take advantage of the Fomantic UI development framework (a branch of SemanticUI) to polish your app’s look and feel

In addition to shiny.semantic, Appsilon has created several more open-source Shiny extensions. You can see the complete offering at

Appsilon announced that two more are on the way: shiny.fluent, a UI framework that lets you use Microsoft Fluent UI frameworks in Shiny; and shiny.react, designed to make React JavaScript libraries easy to use in Shiny.

What would a Shiny app look like with a Microsoft Fluent HI? You can see a demo here:

And, Appsilon said they will make some of their Shiny look-and-feel templates and layouts available to the R community. Some will be free, others will be paid/premium.

Want yet more ideas to up your Shiny game?? The Shiny Awesome GitHub repository lists a lot more Shiny exensions.

Boost Shiny performance

New in Shiny 1.6: bindCache(), which can cache values for Shiny inputs, plots (including plotly plots), and text. For now, you’ll need to install the development version of Shiny to get this functionality:


There’s fairly extensive bindCache() documentation, which you can see by running ?bindCache . Using the function looks pretty straightforward, at least according to demo code shown by RStudio’s Winston Chang:

reactive(...) %>%
renderPlot(...) %>%

That cache function came out of work RStudio did with the state of California, so an early version of California’s Covid-19 dashboard could scale up for an expected 100,000 simultaneous users, Chang said.

Other Shiny performance tips:

Use update functions when creating dynamic input widgets, such as updateSelectInput()

radioButtons("state", label ="Select State",
choices = c("CA", "NY")),
selectInput("city", "Select city:",
choices = c(""))
if(input$state == "CA") {
updateSelectInput(session, "city", "California", choices = c("Sacramento", "Los Angeles", "San Francisco"))
} else if(input$state == "NY") {
updateSelectInput(session, "city", "New York", choices = c("Boston", "Worcester"))
} else {
updateSelectInput(session, "city", choices = c(""))

Use proxy functions if available for rendering more complex widgets, such as the DT package’s dataTableProxy(). You can create your own custom messages similar to proxy functions if there isn’t one available for the widgets you’re working with, Pedro Coutinho Silva at Appsilon advised.

Understand how long you can depend on a tidyverse function

Few things last forever — and code is no exception. In fact, RStudio Chief Scientist Hadley Wickham suggested developers view their code more like a smoke alarm, which needs occasional maintenance and less frequent replacement, as opposed to a monument that can be expected to last for decades.

The popular tidyverse ecosystem of R packages views packages and functions this way. However, that can cause complications for developers who depend on that code for their own projects. So, Wickham said, RStudio aims to offer transparency on how long its code will be available without breaking changes.

tidyverse lifecycle is a bit of a complex subject, Wickham added — in fact, there’s a whole R package devoted to explaining it, called lifecycle. In a nutshell, there are four key life stages for tidyverse code: experimental – likely to change or disappear, use at your own risk for production but do try it out and offer feedback; stable; superseded – they’ve found something better and will recommend a new way, but the old way will be still be available; and deprecated – this generates a warning that the function will likely go away soon in a future package version.

If you don’t want to maintain and update your code but need or want it to be static, Wickham said, you can use the renv package. That creates a snapshot of R and package versions your code depends upon. Or, you can use a CRAN “time capsule” such as Microsoft’s MRAN or RStudio Package Manager (as long as your only dependencies are CRAN packages).

Exchange data with others – including Python and JavaScript users

The pins pkg aims to make it easy to push and pull data between your local machine and services such as AWS, GitHub & Kaggle. There’s also a function to search for data sets. Now, the new pinsjs project offers the same functionality to JavaScript and Python, project lead Javier Luraschi said.

More info:



Next year’s conference

RStudio is planning for an in-person conference next year, March 7-10, 2022 in Orlando, Florida.