Skip to main content
AI in Production 2026 is now open for talk proposals.
Share insights that help teams build, scale, and maintain stronger AI systems.
items
Menu
  • About
    • Overview 
    • Join Us  
    • Community 
    • Contact 
  • Training
    • Overview 
    • Course Catalogue 
    • Public Courses 
  • Posit
    • Overview 
    • License Resale 
    • Managed Services 
    • Health Check 
  • Data Science
    • Overview 
    • Visualisation & Dashboards 
    • Open-source Data Science 
    • Data Science as a Service 
    • Gallery 
  • Engineering
    • Overview 
    • Cloud Solutions 
    • Enterprise Applications 
  • Our Work
    • Blog 
    • Case Studies 
    • R Package Validation 
    • diffify  

Top 5 Shiny UI Add-On Packages

Author: Mandy Norrbo

Published: October 27, 2022

tags: r

There are a growing number of Shiny users across the world, and with many users comes an increasing number of open-source “add-on” packages that extend the functionality of Shiny, both in terms of the front end and the back end of an app.

This blog will highlight 5 UI add-on packages that can massively improve your user experience and also just add a bit of flair to your app. Each package will have an associated example app (some more inspired than others) that I’ve created where you can actually see the UI component in action. All code for example apps can be found on our GitHub.

Do you require help building a Shiny app? Would you like someone to take over the maintenance burden? If so, check out our Shiny and Dash services.

{shinycssloaders}

If you have graphs or other outputs in your app that are slow to render and re-render, it can be frustrating for the user if it looks like nothing is changing after they’ve changed an input or pressed a button to re-render. Adding a spinner to indicate the plot is re-rendering makes it clear to the user what is going on and can make that waiting time a bit more bearable!

While the {shinycssloaders} package does not speed up your plot rendering (although if you do need help with speeding up a Shiny app, we can help), it does let you very easily add loading spinners to any specific output in your Shiny app.

All you need to do is wrap your Shiny output in the withSpinner() function! You can also modify the spinner with the type, color, and size arguments.

# in the UI
withSpinner(plotOutput("my_plot"))

In my example app:

A gif of a plot being re-generated with a shinycssloader showingduring rendering.

{waiter}

{shinycssloaders} is very useful if you have one or more slow outputs that need to be rendered or re-rendered, but what if just loading up your app at start up is slow? For example, if you’re pulling new data from an API or a database every time you load the app. This is where the {waiter} package comes in handy!

{waiter} allows you to create a loading screen that covers the entire app until some specific bit of code has finished running. You just need to tell it when to show (waiter_show()) and when to hide (waiter_hide()) the waiter loading screen. Note that you’ll need to activate the waiter functionality by including the useWaiter() command in your UI.

The basic syntax is:

# in the UI
useWaiter()

# in the server
waiter_show()

  # code that takes a while to run

waiter_hide()

In my example app:

A gif of a an app being refreshed with a loading screen created by thewaiter package.

{rclipboard} & {tippy}

If your app needs to generate any kind of text that would then need to be used elsewhere, e.g. a URL or a uniquely identifying string, then a “Copy to clipboard” button can easily be added with the {rclipboard} package. The main function from {rclipboard} is rclipButton() which creates a clickable button that lets you copy whatever is passed to the clipText argument. There are no associated render*() or *Output() functions, so you can create your clipboard button and then render it with renderUI() and display it with uiOutput(). You will also need to activate the copy to clipboard functionality by including the rclipboardSetup() command in your UI.

A basic button could be created like this:

# in the UI
rclipboardSetup(),
uiOutput("clip_button")

# in the server
renderUI({
  rclipButton(
    "clip_button",
    "Copy to clipboard",
    clipText = "Text to be copied",
    icon = icon("clipboard")
  )
})

However, when you press this button there is no feedback to the user that anything has actually been copied. This is where the {tippy} package comes in. {tippy} allows you to add tooltips to UI elements in your app that appear at a certain trigger such as hover or click. Tooltips are an effective way to provide help or feedback to the user and improve their experience using the app.

All you need to do is call the tippy_this() function on the input ID of your UI component. If we have a clipboard button with ID clip_button as above, we could add a tooltip that says “String copied!” whenever the button is clicked.

# in the UI
tippy_this(
  "clip_button",
  tooltip = "String copied!",
  trigger = "click"
)

In my example app:

A gif of a random string being copied to clipboard with tooltip pop-upand then being pasted.

{shinyglide}

{shinyglide} lets you create a carousel-like window that allows the user to move between different screens in a chronological order using “Next” and “Back” buttons. It’s a nice way to add a pop-up to guide your user through some action, either for collecting inputs for your app, or demoing how to use the app, or just as an embedded presentation.

There is a lot of flexibility when using {shinyglide}, but a basic series of screens could be constructed like this:

# in the UI
glide(
  screen(
    # content on the first screen
  ),
  screen(
    # content on second screen
  )
)

A nice feature is that you can easily add a condition that needs to be met until the user can move on to the next page, e.g., the user needs to provide some input. This is done with the next_condition argument in the screen() function.

In my example app:

A gif of three shinyglide screens being moved between using Next andBack buttons.

{sortable}

Last but not least is {sortable}, which is a package that enables drag-and-drop behaviour in your Shiny apps. This means that the user can perform actions such as rearranging plots in a grid, or include/exclude elements by dragging them in and out of a specific panel.

The basic syntax of {sortable} is:

sortable_js("element_id")

where "element_id" is the ID of the div containing the elements you wish to be drag-and-drop-able.

In my example app:

A gif of four plots in a grid where two are swapped by using drag anddrop with the cursor.

Further resources

If you want to explore even more packages that extend the Shiny framework, I would highly recommend checking out this curated list of Shiny extension packages:

  • Awesome Shiny Extensions

Jumping Rivers Logo

Recent Posts

  • Start 2026 Ahead of the Curve: Boost Your Career with Jumping Rivers Training 
  • Should I Use Figma Design for Dashboard Prototyping? 
  • Announcing AI in Production 2026: A New Conference for AI and ML Practitioners 
  • Elevate Your Skills and Boost Your Career – Free Jumping Rivers Webinar on 20th November! 
  • Get Involved in the Data Science Community at our Free Meetups 
  • Polars and Pandas - Working with the Data-Frame 
  • Highlights from Shiny in Production (2025) 
  • Elevate Your Data Skills with Jumping Rivers Training 
  • Creating a Python Package with Poetry for Beginners Part2 
  • What's new for Python in 2025? 

Top Tags

  • R (236) 
  • Rbloggers (182) 
  • Pybloggers (89) 
  • Python (89) 
  • Shiny (63) 
  • Events (26) 
  • Training (23) 
  • Machine Learning (22) 
  • Conferences (20) 
  • Tidyverse (17) 
  • Statistics (14) 
  • Packages (13) 

Authors

  • Shane Halloran 
  • Russ Hyde 
  • Myles Mitchell 
  • Amieroh Abrahams 
  • Tim Brock 
  • Aida Gjoka 
  • Gigi Kenneth 
  • Osheen MacOscar 
  • Sebastian Mellor 
  • Theo Roe 
  • Colin Gillespie 
  • Keith Newman 
  • Pedro Silva 

Keep Updated

Like data science? R? Python? Stan? Then you’ll love the Jumping Rivers newsletter. The perks of being part of the Jumping Rivers family are:

  • Be the first to know about our latest courses and conferences.
  • Get discounts on the latest courses.
  • Read news on the latest techniques with the Jumping Rivers blog.

We keep your data secure and will never share your details. By subscribing, you agree to our privacy policy.

Follow Us

  • GitHub
  • Bluesky
  • LinkedIn
  • YouTube
  • Eventbrite

Find Us

The Catalyst Newcastle Helix Newcastle, NE4 5TG
Get directions

Contact Us

  • hello@jumpingrivers.com
  • + 44(0) 191 432 4340

Newsletter

Sign up

Events

  • North East Data Scientists Meetup
  • Leeds Data Science Meetup
  • Shiny in Production
British Assessment Bureau, UKAS Certified logo for ISO 9001 - Quality management British Assessment Bureau, UKAS Certified logo for ISO 27001 - Information security management Cyber Essentials Certified Plus badge
  • Privacy Notice
  • |
  • Booking Terms

©2016 - present. Jumping Rivers Ltd