Making Shiny Apps Awesome
A week before Christmas our CTO, Marek Rogala gave a speech about ways to make Shiny apps do much more than usual during R enthusiasts meeting in Warsaw. In case you have missed this event, we are brining you the gist.
We often use R and Shiny to create interactive web apps for both internal and commercial projects. What makes those technologies so wonderful is the fact that they allow for easy prototyping of almost any data science problem. There are numerous examples of how Shiny can be used to make an interactive web app, so it’s pretty easy to find inspiration on how to build one by yourself. However, in our day-to-day work we are constantly challenged to do more that is currently possible in Shiny by default. Fortunately, both R and Shiny are highly extendable and Marek spoke about specific problems we were facing in past projects and what R packages we had created to solve them.
The first problem was… creating a smooth user experience and good looking interface.
Although Shiny is a great web framework it does not look beautiful enough for today’s web standards. As our data science team has also extensive web development experience and loved to use Semantic UI from the very beginning of its existence, we decided to combine it with Shiny. We have named this package shiny.semantic. It allows us to create really good looking apps with interactive components, like rating bars or cards, which are missing in Shiny. In 2018 we went further, we created semantic.dashboard which is even more powerful.
All that you get by built-in methods or by adding a few simple CSS classes. But there is more! For instance, you have a huge set of Semantic UI icons and animations too. You can learn more about this package in our previous post.
The second problem we had to face couple of times was … an in-app navigation and state keeping.
In today’s world we are used to making page bookmarks and sharing links with other co-workers. We also expect that app will keep its state, when opening it from a bookmark or shared link and we often want to navigate back in our browser to see a previous state.
Unfortunately Shiny has a very limited support for those. As our blog’s reader you might already know how to solve the issue we created shiny.router package.
During the event Marek discussed details and history of package development. This simple library not only solves navigation issues mentioned above, but also encourages the user to write more structured and better code by writing UI modules.
Last but not least, Marek presented our real-time collaboration solution for Shiny. Although Shiny does support this kind of reactivity, it is limited in many ways.
In a regular Shiny app you may use global scope reactive values that are shared between multiple session and refreshed every time someone makes a change. There are some limitations though:
- state is not persisted, unless stored and initialized from database
- this data cannot be used outside of Shiny apps, which makes it difficult to analyze the content in those reactive values
- scalability – apps hosted on shinyapp.io can handle a few hundred users and Shiny Server Pro instance will support up to 200 users depending on a chosen license
In order to solve some of those issues we have created a wrapper for Reactive real-time databases (eg. RethinkDB, Firebase). It allows us to easily recreate a state of an app (state can be easily stored per user) and all tables and reactive values are synced between multiple sessions. For example we can span multiple Shiny apps processes and connect it with one real-time synced reactive database. So to satisfy the requirement of 10 thousand concurrent users we just have to run 50 Shiny Server instances with a load balancer in the front.
If you didn’t have a chance to hang out with Marek during R enthusiast event feel free to get in touch with us to talk more about any of these topics. 🙂