3MW (Improve Your R-Shiny App With Modules)

Guten Tag!

Many greetings from Munich, Germany. Today we talk about Shiny modules. That’s a must-know concept for anyone who wants to build semi-elaborate Shiny apps. And a lot of people treat modules like a highly advanced concept. But it’s not. It is a must-know concept that you better learn as early as possible.

The thing is: Shiny apps can get really bloated really fast. And it’s hard to debug and maintain these kind of monolith apps. The code base simply becomes unbearable if everything lives within one app.R file.

And that’s where modules come in. They allow you to spread out your shiny app code into (reusable) parts. And that’s what we are going to talk about today. But before we dive into that, let’s talk about this week’s announcements.

Clean data with the janitor

I can’t live without the {janitor}. I use its clean_names() function in every data analysis. But I’ve come to realize that this package has many more convenient data cleaning helpers. Especially when you work with Excel files. In my newest video, I show you what this package can do.

As always, all code that you see here can be found on Github.

Modules as Reusable Components

Imagine that you have an app that uses very similar code for multiple different things.

In this app, the only thing that is different is the dataset that is used. So you have quite some code that is duplicated. And the important thing is that you can’t just throw this into a function. That’s because we have to work on both the UI and the server side. And that’s where modules come in.

They are a bit of work to set up at first but once you’re done, you can use that module over and over again. This is particularly useful because you don’t have to come up with unique IDs for each part of the duplicate code.

Creating Modules

To create a module, you need to create the UI and server module functions. These are different from your original app UI and server functions.

If you use RStudio, there is already a built-in snippet to throw a skeleton for these two functions.

Filling the module UI

Once you have these, you can more or less throw your UI code from your original app into the tagList() of the module UI function. But one thing that is really crucial is wrapping all IDs into the ns() call.

This step is really important. If you forget to use ns() (and you will), then you won’t get an error. But your app won’t work as expected either. And that can be really annoying. So when in doubt, check if you wrapped all IDs into the ns() function.

I would even go so far as to say that this is the golden rule of debugging Shiny modules. I can’t count the number of times I forgot to wrap an ID into ns() and then wasted ages trying to find some complex error in my code logic that wasn’t there.

More importantly, the ns() might feel tedious but it actually does a good thing for you. It ensures that you don’t have duplicate IDs (which won’t fly with Shiny) without you having to worry about how to set that up.

Filling the module server

With the server function, you don’t have to worry about the ns() function. You can just take your original server code and throw it into the function inside of the moduleServer() function. And if that code requires another variable (like dataset in our case), you can just add that as an argument to the module server function.

Sticking modules into your app

And once all of that is done, you can

  • take the UI module function,

  • stick it into your app’s UI,

  • assign a unique module ID, and

  • do the same for the module server function in the app server.

And the nice thing is that this scales well with more repetitive app elements without bloating your code.

Further learning

This was a very basic example of how to use modules, but the really crucial thing is that you get the mechanics right. Once you understand this mundane example, you can check out this video next where I explain modules in a video in 100 seconds.

And if you need more examples of how to use shiny modules, check out this:

Nice! With that we have unlocked an INSANELY powerful tool. Next week, I’ll share a bit more on the philosophy of how to use modules in your app development process. And if you have any questions don’t hesitate to reply to this mail or contact me on LinkedIn.

See you next week,
Albert 👋

Enjoyed this newsletter? Here are other ways I can help you:

Join the conversation

or to participate.