Join the Shiny Community every month at Shiny Gatherings

Photo by William Iven on Unsplash

5 Signs It’s Time To Refactor Your Shiny Dashboard

Everybody loves a good dashboard. They are the best way to visualize data and provide insights. As the requirements get longer and time frames get shorter, dashboards can quickly become a nightmare to maintain. That’s where refactoring comes into play.

Are you developing dashboards in Python and Dash? Here’s when and why you should switch to Shiny.

Here are the top five reasons why you should refactor your Shiny dashboard:

It Takes Minutes to Scroll Your Server/UI Files

The backbone of Shiny applications are server.R and ui.R files. Usually, the app starts small within those files and then starts to grow. Finally, it reaches the state when navigation through the logic becomes next to impossible.

That is the perfect case for introducing Shiny modules. Their main purpose is to avoid code duplications, but they are also great for organizing the app. 

Each Shiny module consists of its piece of Server and UI logic, small enough to swallow and digest. Modules also separate the namespaces, so you don’t have to worry about setting the same ID for different buttons.

The perfect Server and UI calls these modules and points the developer to the appropriate script for the particular functionality. 

Your Reactivity is Like Spaghetti

Reactivity is what makes Shiny applications so great. It is easy, intuitive, and works nicely. However, for complex apps, it can quickly get out of hand and behave unexpectedly. 

The Shiny developer’s nightmare is when the app starts to refresh itself due to some unplanned event. Even worse is the race condition – the situation when your observers behave differently on each run depending on which was triggered first. Whenever you start adding the “priority” argument to the observers, it looks like a time to stop and rethink.

The idea to solve this problem is to avoid reactivity whenever possible. For example, widgets shouldn’t be created with renderUI in the Server but directly in the UI. You should then use the “update” type of functions to control the flow better. 

Some actions can only be performed in the browser via JavaScript, not even to bother reactivity.

Want to make Shiny faster with JavaScript? Here’s a guide to get you started.

Another approach to simplify reactivity is to move the code logic to functions and classes that aren’t using it. That way, these functions can be triggered whenever they are needed.

You Want to Introduce Unit Tests, But Don’t Know Where to Start

Unit tests are a crucial concept in programming. For Shiny apps, it is not always easy to implement them. Implementation might also require some refactoring. 

If you’re about to introduce unit testing (probably with the testthat package), but you find it hard to find what to test, it is an indicator that too much logic is put directly into Shiny. 

It is very tempting to have objects in the Shiny environment and modify them directly through the reactive/observers’ logic. This approach is prone to errors and nearly impossible to unit test.

Make sure to move the logic to easily reusable and testable functions and classes. It will help if they are reactivity-free. The Shiny layer should be as thin as possible and only call the appropriate functions when needed.

Finally, if you already have a mature Shiny application but no unit tests implemented, it is time to work on that and refactor ASAP.

You Copy-Paste the Code

The easiest mistake to spot and solve. Whenever you copy-paste the code logic, it is time to stop and rethink what you are doing. It is rarely a good idea. 

Extract the logic to the separate function or module, and you should be good to go. 

Creating a package would be better and allow you to reuse the logic within the application and between the applications. And of course, don’t forget to add unit tests to the newly extracted logic.

The App Performance is Making You Sleepy

“Hello World” Shiny application is blazing fast. However, as you add more and more things, it can quickly become slow and annoying. 

It can be caused by redundant reactivity and useless going back and forth to the Server while staying inside the browser (see 2.). 

The other common reason is overloading the app with the data processed in memory. Usually, there is no need to use whole big datasets in the Shiny application, but rather let the user filter it out first to some reasonable piece to analyze. 

The plumber package allows us to create a smart API to the database and load only data that is needed – thus making the application fast and enjoyable.


And there you have it – top why reasons why you should immediately refactor your Shiny application. There are others, of course, but these five are the most common ones we encountered in years of developing Shiny apps. 

If you want to make a scalable enterprise Shiny dashboard, then you can always reach out to Appsilon for help. We’re continually pushing the limits of what’s possible with Shiny, and we’d be happy to guide you and your company.

Learn More

Appsilon is hiring for remote roles! See our Careers page for all open positions, including R Shiny Developers, Fullstack Engineers, Frontend Engineers, a Senior Infrastructure Engineer, and a Community Manager. Join Appsilon and work on groundbreaking projects with the world’s most influential Fortune 500 companies.