
Design of Everyday Shiny Apps (Casey Aguilar-Gervase & Maya Gans, Atorus) | posit::conf(2025)
Design of Everyday Shiny Apps Speaker(s): Casey Aguilar-Gervase; Maya Gans Abstract: Donald Norman’s Design of Everyday Things shows how even smart people struggle with bad design—flipping the wrong switch, pushing a door instead of pulling. The same issues exist in Shiny apps, where function often outweighs experience. But as a Shiny developer, you are the door designer, and it’s your responsibility to create user-friendly tools. Not to worry—good design isn’t just for designers. You don’t need an art degree to build intuitive, visually appealing apps. This talk covers composition, color theory, scale, and proportion—practical rules to improve usability. We’ll show real-world examples and code-based strategies to bring these principles to life. Because good design isn’t a luxury—it’s a necessity. Materials - https://github.com/caseyag/Posit-Conf-25 posit::conf(2025) Subscribe to posit::conf updates: https://posit.co/about/subscription-management/
image: thumbnail.jpg
Transcript#
This transcript was generated automatically and may contain errors.
Hi, everyone. I am Casey Aguilar-Gervase. And I'm Maya Gans. And this is the design of Everyday Shiny Apps.
Pop quiz. You approach this door. Are you going to push or pull it? That moment of hesitation and, frankly, feeling stupid? We're here to tell you today, this is not your fault. This is the fault of the door.
In Don Norman's seminal work, The Design of Everyday Things, he talks about how door handles, specifically, should be designed either to push or pull. Not both.
In this talk, we'll be pulling imagery from Camprani's Uncomfortable series. We love this imagery because it so beautifully evokes the frustration of bad design.
We noticed this morning that Jonathan's talk also used this imagery. His jumpsuit got lost in the mail, I guess.
But this talk is not about watering cans or doors. It's about Shiny applications. And you may have come to this talk thinking that design is about making aesthetic or pretty things. But we're here to tell you that no. Design is about utility and making users feel like they can use an app and trust it.
So if you couldn't tell by our outfits, Maya and I are pretty used to pair programming. We work together as Shiny developers in consulting. And our job is to connect function with feel so client applications can move from it runs to it's usable and clear. This talk is going to be intentionally practical. It's what our day-to-day kind of looks like when we're turning proof of concept applications into something not only functional but genuinely enjoyable.
So in this talk, we're going to go through four lenses. Layout, making it scannable and predictable. Color, aiming attention without extra words. Typography, setting a clear hierarchy that holds up in dense data. And components, the answer to what's happening, what changed, what do I do next?
So these four lenses are how we take a proof of concept and turn it into something production-ready that's on brand. For today's examples, we're going to use a fake client brand kit. So this is what our client gave us. Five main colors and a single typeface to use. That's it. As we walk through layout, color, type and components, you'll see us apply the basics. Nothing fancy to drive consistent choices.
Walking through the original app
So here's where things get fun. In the next slide, we're going to walk through the original app the way we first experienced it. So great. I see some data when I open the app, but I'm unsure. Can I come back to this when I press this close button?
The color palette hits us all at once. It's bright. It's loud. Kind of like us. Instead of guiding the eye, it's pulling my attention in different directions. The navigation feels confusing. Sections don't flow as expected. And it's not clear what I should do next.
So let's try to add a project. I'm going to click this create new button. But now I'm a little stuck. I'll try updating the project name. But nothing seems to happen when I click this.
Maybe let's try deleting. The same thing is going to happen with the delete button. Unsure if they're broken. So I'm going to navigate over to the nested nav. It's probably important. Okay. So this is where I can download my reports. Click on the button. I think this is broken, too. And also, where can I find my file?
Okay. So between the overwhelming visuals and unclear layout, it's easy to see how quickly a new user could get lost or frustrated.
Layout
So when designing an application or redesigning, the first thing that Casey and I do together is look at the layout. This is the map for the user to know when and where to go and what actions are most important.
In this visual, we have a great door and a set of stairs. But without connecting those components, this is pretty useless.
So the client, our client, told us that they wanted to keep the content the same but make the app cleaner and more user-friendly. So we do have a sidebar here that's used as that main navigation. And across the overview page, there's some odd spacing. We kind of see a grid. But it's confusing where my eyes should go because of the inconsistent spacing.
So to make sure the content takes up as much of the real estate of the page as possible, we'll use a horizontal navigation. We've stripped away color here to focus just on layout and an even grid. Small details like consistent layout and spacing help things feel like I can breathe as our eyes or as my eyes are going to absorb the page.
On the overview page, that data table sat at the bottom of the card, and it kind of spilled over. Because it was at the bottom, we had to scroll to see all of the data. We've added a nested nav inside of the overview page so users can flip between the exploration and data review a little bit more seamlessly.
When I added projects, it showed up in this sidebar, but nothing really signaled me to click over there. Once I did, I saw the current selections and download options, but I lost that project table. So now current selections and the project table live together on this left-hand side. And when I go to add a project, that download card is going to appear with a nested nav. So everything's going to stay on one page, the flow is clearer, consistent with that top navigation, and the layout still feels breathable as I'm moving through it.
So what's the TLDR? The takeaway of takeaways today is obey the grid. Evolutionarily, we crave that structure. Your users, there will be a sense of calm if you stick to your columns and rows.
Secondly, shout out to talk before this one, there's been many studies on saccade, or eye movement, and in Western cultures, we read in a Z from left to right. You'll note that we took the navigation from being vertical to horizontal and also put it in that hot spot of the top left corner because that is how you're going to navigate throughout the application.
Lastly, we appreciate that screen real estate is expensive and you want to cram a bunch in there. Don't. That is incredibly overwhelming to your user. You should let different elements breathe. It gives a sense of pause and you can flow through different elements logically.
Color
Okay, so now that we have our layout, we get to the fun part, color. And in this talk, we've constrained it to a defined color palette. Picking colors, that is a talk in and of itself. But today, we're going to talk about how to use color.
So in this example, this bar on the left-hand side, that is the exact same shade of gray. Note how that changes just by what it's placed next to. Similarly, the cells A and B, also the same. We'll give you these slides, you don't have to take my word for it.
This demonstrates how color should not only, you have to make good choices, but you should use those in an effective manner. And when you use color effectively, it almost just hides in the background and becomes transparent.
So in the original app, the color palette is here, but it feels a little bit chaotic and distracting. We also see the default Shiny blue that's showing up in the slider and a pink in that checkbox that doesn't quite fit.
Taking advantage of the new layout, we're adding color more intentionally. There's a pop of gradient in the nav and that same gradient shows up as an accent in the value cards. It's not distracting, but it adds unity and ties the color palette together.
Color now works as a guide. Active tabs in the nav have a pink underline and when I hover, the color shifts to our watermelon secondary color.
On the report page, buttons didn't really have a lot of styling, they're just pretty much Shiny default. Buttons are now gonna mirror the nav styling, pink by default, shifting to watermelon on hover. So these color accents create consistency across interactions.
In tables, the hover state defaulted to the standard data table blue. The hover state now uses our brand's blue, reinforcing the palette and creating subtle unity. These small color decisions don't just decorate, they build consistency, trust, and a more polished user experience.
How do I do this myself? One, start designing in black and white, slowly integrating and adding more color. Two, stick to a defined palette. You get five colors and we're being generous. Note that two of those colors were black and white.
In Flex Dashboard, I'm pretty sure the background is a default of a lightish blue. None of that if it's not in the palette. And lastly, use color to highlight. Clearly we like flair here, but I'm not gonna make a navigation bar hot pink just because I want to. That's where Casey edits me and says, we use color to highlight and show interactivity within the application.
Typography
Once we've tackled color, we move on to typography. Font nerds collect fonts like baseball cards. Font sets the tone and tenor of your application. You can have a fun, silly font or very serious, and you also can use typography to create hierarchy. The importance of font is shown in this photo. It can be used to convey something delicious or something entirely different.
So in the original app, there isn't a super clear hierarchy established across the elements. Font weight is here, but it doesn't feel super intentional. We're also missing the brand's typeface.
So to start, the new app uses the brand typeface throughout and value boxes uppercase and size, improve readability, and make distinctions clearer at a glance. All user input labels are uppercase and bold, reinforcing consistency. Font weight is gonna be used purposely, like showing emphasis when hovering in the nav.
On the report page, elements blended together without clear separation. Font weight now highlights headers while buttons use case to place emphasis.
So this consistent use of weight, case, and readability patterns across inputs is gonna build subconscious trust for the user.
Rule number one, match your style to the brand. You're given a typeface, use it. If that typeface is super funky, do not use that for smaller fonts. Pair it, and just like we gave you five colors, you get two fonts tops, even that, generous.
Casey showed us how you can also increase the font weight, and in those value boxes, we had the titles were uppercase and the bylines were lowercase. Those were the same font. Those two are tools you have in your arsenal. You don't just have to increment the font size. However, if you are going to, be consistent. We like incrementing by four or six pixels. Do not just willy-nilly big, medium, small.
Components
Our last section is components. These are the pull and push doors of your application, and what's gonna make it or break it for users to keep on using your app or just go on to the next one.
This is made evident in this image where there's a blow-up door handle. If you try to turn that and it squishes in your hand, you're not going anywhere.
To start, in the original app, the modal was really the only way for the user to access details, which is gonna force me to memorize information from one screen to the next. We added a persistent tool tip at the top, so instead of relying on memory, users now have a reference point that they can turn to at any time.
On the report page after adding a project, there was no clear direction forward, no labels, no guidance, just buttons kind of staring back at me. It was a moment where users might easily hesitate or give up. Section-level tool tips now give descriptions of what each area is for and how to use it. Buttons only appear when needed, guiding users through the flow without overwhelming them.
For permanent actions, like deleting, we added a confirmation step as a safeguard, which you can see here with this delete modal that's popping up.
The original download button was kind of a mystery. I just click it, hope for the best, kind of like sending a text into the void. The download button now comes with a progress bar and error message, so users know the app heard them and what might be happening next.
As a bonus, custom HTML widgets like this one, which uses hands-on table framework, can create familiar Excel-like tables that still feel intuitive to use while maintaining our brand identity. So together, these changes really reduce confusion, build confidence, and turn something overwhelming into something guided and responsive.
Visual feedback is key. For every action a user can take, there must be some reaction in the application that showed them that they took this action.
Error prevention. As a good rule of thumb, any action that your user can do in the application, they should be able to undo. If you have a situation in which they can't undo it, like Casey demonstrated, you should pop up a modal, you sure about that?
And lastly, progressive disclosure, which was a great point in the previous talk, that the Shiny apps that we've asked to redesign the Shiny folks here, they love a wall of text. And let's be real, no one's reading that. Put your text in chunks in information tool tips so that when I go to that plot, I interact and hover over it, ooh, what does this do? And similarly, put that by your filters, break it up into ways people will actually read.
Put your text in chunks in information tool tips so that when I go to that plot, I interact and hover over it, ooh, what does this do? And similarly, put that by your filters, break it up into ways people will actually read.
Why design matters
So at this point, I hope not, but you might still be wondering, why should I care about all this design stuff? The truth is, design is the difference between an app people tolerate and a people actually use.
If the layout is confusing, users are gonna get frustrated and drop off. If the tone feels off, they just don't trust it. And if the app doesn't give clear feedback, they might make mistakes or give up entirely. So that's not just about looks, that's about adoption, efficiency, and whether your work even lands with its audience.
We thought this quote was the perfect way to end our talk because it covers how layout, color, type, and components are all integral to good design, and good design is not a luxury, it's a necessity. Mic drop.
good design is not a luxury, it's a necessity.
So if you scan this QR code, it'll take you to our GitHub repo where you can find literally everything from today's examples. The different branches are gonna walk you through piece by piece how we developed this app, so you can kind of walk through the black and white layout, color, type, as we add things in. So thank you.
Q&A
All right, so a couple of questions. The first one, is dark mode toggled the work of the devil?
Oh, that's a good question. I think with a lot of what we try to do specifically for Pharma, a lot of it is starting from a blank canvas, so whether that is white or dark mode. I know all of my not apps, you know, my computer, is all dark mode. So maybe I should have done a dark mode example. Dark mode is awesome, it's really hard to do well.
How do you start designing in black and white when Shiny apps start up with default colors? That is a great question. So with BS Lib, I think it's pretty user-friendly to be able to set your primary, secondary, and tertiary to black, gray, and light gray. Light gray is technically darker than gray, but that's a different talk. So you can do that, and then build from there.
All right, last one. What code strategies do you suggest for consistency in Shiny UIs? Do you use helper classes only, like bootstrap material, et cetera, or pure SAS or CSS?
I think BS Lib has, like Maya just said, provided a really easy way to, like for color, for example, set colors. There is, even for this app, and looking at the repo, there is a bit of CSS-ing that's involved to get some of the custom colors, but I think with having those variables defined at the top of a code with BS Lib, it does make it a little bit more streamlined. All right. Let's give Casey and Maya another round of applause.
