3MW (Shiny's module-first approach)

Guten Tag!

Many greetings from Munich, Germany. In today’s newsletter, I want to explain the philosophy of how to use modules to add new features to a Shiny app. But before we do that time for my usual announcements.

Why you shouldn't rely on box plots too much

Box plots are a popular tool in data visualization. But they do have a crucial flaw. In my newest video, I show you what the problems with box plots are and how to do better. You can find that video on YouTube:

As always, you can find the full code of this newsletter on GitHub.

The scenario

Imagine that you have a semi-elaborate shiny app already. And now imagine that you want to include a new table that displays a specific data set which can be selected via a drop-down menu. In this case, there are (at least) two ways of adding this new feature to your already existing app.

And as you can guess, one way is much better than the other. Unfortunately, it’s really easy to fall into the worse way’s trap (which is what I did in my Shiny beginnings too.) So let’s have a look at those two approaches.

What not to do

It is really easy to create monolithic apps. These are apps where all the code lives within one gigantic app.R file. But believe me these kind of apps are an incredible pain to work with.

The thing is, the larger your app gets, the harder it is to maintain and figure out how all the parts play together. And especially when you have a whole lot of reactivity, things get really confusing really fast.

No one really sets out with the goal of creating a painfully annoying code base. Instead, everyone starts off with a tiny app and then adds a tiny new feature one-by-one. And that’s where the danger is.

Adding these tiny new features is often easy. Just add a few lines of code to your app.R file and you’re good to go. But this is a sure way to a monolithic, hard-to-maintain, no-one-ever-wants-to-touch-that-code app.

So instead, try to split your app into small self-contained pieces as soon as possible. And that’s where the module-first approach comes in.

The module-first approach

We’ve already learned how Shiny modules work. And the fact that they consists out of a UI and server makes them perfect for creating self-contained app pieces. Let’s come back to our example of trying to add a new feature to see how that works.

We want to display a table and change the data that is displayed via a drop-down menu. A module for this could look something like this.

Notice how small this code base is? That’s exactly the point. And I know that creating a module for this can feel like overkill. It’s just one small table and a dropdown menu after all. But believe me, you want too err rather on the smaller module side.

One module = one app

Okay, so big deal. We have a module now. Time to throw that stuff into our main app, right?

Well, don’t be so fast there. With the module-first approach comes a corollary. And that’s “one module = one app”.

So, don’t go and throw the new module into your app immediately. Instead, create a new Shiny app that just consists of a page with that module UI and with the server UI.

Admittedly, this app will look really boring. But that way, you can

  • work exclusively on that new feature,

  • debug a couple of things, and

  • iterate until it does exactly what you need.

Only then do you copy the module to your full app.

But don’t throw away the small app. Instead, keep all of the module definitions and this small app in a separate file. If you want to add more features to your table later on, you will be glad that you still have the mini app to iterate on the additional feature.

Advantages of the Module-First Approach

As you can see, the module-first approach is really a three stage process:

  1. Create a module,

  2. test that module on a small app, and

  3. only then copy the completed module to the full app.

I know that this might feel a bit excessive but it comes with a few advantages:

  • It’s much easier to work with

  • It’s much easier to develop because you can launch your mini-app really fast

  • In your smaller module app, you don’t have to wait for all of the other features of your app to load

  • You can come back to just your module code and the corresponding dummy app if you want to enhance that feature later on (which you will probably will)

With that, I hope that you have an idea of how to improve your Shiny development workflow. Next week, we’re going to be more technical again as we talk about how to share data between modules. That’s a crucial step so that you can indeed break down your app into very small pieces and have them all communicate with each other.

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:


or to participate.