Kamil Zyla | Introducing Rhino: Shiny application framework for enterprise | RStudio (2022)
R and Shiny are ready for production use in Enterprise. As Appsilon, we have worked with tens of top global companies on their Shiny projects. Emphasis on UI, monitoring users’ behavior, and solid engineering principles made the difference. These are some of the practices that made projects impactful. We want to help ourselves and the community to leverage best practices that have worked for us so far. That’s why we built Rhino - the new framework for Shiny in Enterprise. Kamil Żyła is a senior software engineer at Appsilon and Rhino’s creator. He will share our experiences in ensuring the success of Shiny projects. You will see why you may want to try Rhino in your next (or current) project! Session: I like big apps: Shiny apps that scale
image: thumbnail.jpg
Transcript#
This transcript was generated automatically and may contain errors.
Have you ever been in need of a tool that you didn't have? Imagine that you have this screw that you need to unscrew, but you don't have the right screwdriver to do that.
So what do you do? Go to the nearest hardware store. You look at the various screwdrivers they have, bigger, smaller, different screw heads. You pick the one that will match your screw, you bring it home, you unscrew, you're good.
Some time passes. You want to find a table that will match the space between your sofa and the wall. But you don't have a measuring tape, and you need one. So what do you do? You go to the nearest hardware store, look at the various measuring tapes they have. Longer, shorter, thinner, wider. Start wondering why that even matters, but you need to make a decision. So you pick one, bring it home, measure, you're good.
Some time passes. You need to hammer a nail. So what do you do? You start wondering, wouldn't it make sense to buy a complete toolbox instead of assembling one tool by tool?
The problem with assembling tools one by one
My name is Kamil. I'm a full stack engineer at Appsilon. We specialize in building Shiny applications. Let me tell you of a typical situation that we faced many times over in our work.
So a client comes to us and asks whether we could build an application for them. Using wonderful capabilities of Shiny, we create something within a couple of hours that is interactive and impresses the client. Contract signed. The project starts. A couple of weeks pass. The code base grows 20 times. And realize that we are spending a lot of time discussing the code style, where the opening brackets should be.
We figure that we need some tool that will automatically check this for us. We need a linter. So what do we do? We find linter, we configure it properly, we add it to the project, we start linting our code, we're good.
Some time passes. We realize that we touch one place in the application and something else breaks. So we figure that we should start writing tests. We need unit tests. What do we do? We find test that, we configure it, we add it to the project, we start writing unit tests. We're good.
Some time passes. And you get the point. Needs keep arising and we need to keep addressing them. You start wondering, wouldn't it make sense to start with a complete development toolbox instead of assembling one tool by tool?
This goes deeper, though. In case of development tools, introducing them later on in the project is typically more costly. For example, if you want to add linter when you already have hundreds of linter errors, you'll first have to fix them all. And that's not only a lot of work, but you need to synchronize it with your team.
But we should take even a wider perspective, though. It's not just one project. It's multiple teams dealing with multiple projects at the same time. And similar needs arise in each of those projects. And each team keeps configuring the same tools. Wouldn't it be wonderful to have just one universal toolbox? All this effort could be directed into really polishing it instead of reinventing the wheel all the time.
Moreover, in an organization, when you have just one universal toolbox, people get proficient using it. So when you start a new project or move to a different one, everybody's up to speed right from the beginning. This can really bring the productivity to a whole new level.
This can really bring the productivity to a whole new level.
The origin of Rhino
So you can see what kind of problem we have here. And this is where my personal story begins. Right here in the middle. So I joined Epsilon two years ago in July. It was a hot month. My birthday was coming. It was the last month of our only office being open. Pandemic was raging. Lots of things were happening.
So my first project was called Project Patterns. What was that? Well, technically speaking, it was a Git repository with snippets of code on branches and a related Python tool that could be used to combine them into project structure for new and existing projects. Sounds complicated? It was. And it was my task to improve it.
So first of all, I tried to understand the purpose of all this. And I started researching what we tried to do about this in the past. And it turned out that we did a lot. Like years before already, we had discussion groups. And we had a repository of code snippets that could be reused to some extent. Directly before Project Patterns, we had something called... We had a setup involving RStudio in Docker and a related bash tool that could be used to automate some of the things.
So I realized that already many people before me tried to solve these problems that we had. And I had a week to improve that. You can guess that I didn't manage to fix everything within that week. But for the following two years, we kept improving what we had. For example, we went through a phase of simplification, where instead of having all this complex set of tools, we created just a simple, shiny template. A Git repository that could be cloned and used as a basis for your project.
We also researched other tools. For example, we took a look at Golem. We tried to learn how it differs from our approach. We tried to learn from it. We considered whether we could just use it. For two years, we kept addressing needs as they were arising, resolving issues as they were surfacing. And finally, in the year 2022, we started feeling that we have something that we want to share with the world. And thus, Rhino was born.
No, not just Rhino. Rhino, the free and open-source R package, which we announced in May this year during Appsilon Shiny Conference.
What's inside Rhino
So it's an R package. Means it has functions. For example, this Rhino init function. It creates a new Rhino project for you. So what do you get inside? Perhaps the most obvious part is the full project structure of files and directories. So we have places for configuration, source files, dependencies, tests. Everything is covered from the beginning. So let's take a deeper look at some of those.
Any project will need other R packages to do its job. And it's very important to be explicit about what these other packages are and what versions you need. If you are not explicit about that, you might find that when you try to launch a project after a couple of months, it doesn't work. Why? Who knows? Maybe some package got updated and it broke. If you have an explicit list of dependencies, the chances that it will just work are much higher. And we have R package to deal with this.
For a similar issue but related to the R sources themselves, we have the box package. This one allows you to use Python-style imports at the top of each file so that for each file it is immediately obvious what packages, functions, and other files it needs.
So moving on to the quality of R code. We have three packages which deal with that. For writing tests, we have test that package. Then we have lint R, which can be used to automatically test the style of your codes and also detect some errors that you might have. And we have the styler package, which is able to fix many of those problems automatically. All these tools can be run using Rhino functions out of the box. You don't need to configure anything. Just do, for example, Rhino lint R, and you get your code linted.
So in enterprise settings, typically you will have some needs that will be quite common. For example, one of them is logging. It is very important to output good log messages from your application. If it breaks, for example, in production, this kind of log messages can really help you to find what the issue is. And we have the logger package, which deals with that.
Then you typically will have more than one environment. You will have the local one when you develop the application. Then you will have staging where you will be testing it before pushing it to production. And to manage the differences between these different environments, we have the config package.
Now in any big project, we realize that sooner or later we need JavaScript. We need to customize the application beyond what's provided by our packages. And we figured, why not use the state-of-the-art tech for that? So for JavaScript, we will run your code through Babel and Webpack. This to ensure that you can use the latest features without worrying about browser support. We have SLint that you can use to check the quality of your JavaScript code and also fix many of the errors automatically. While these things need Node.js to be installed on your machine, when using it from Rhino, you will just call the package functions, build.js, lint.js.
Now similarly, we typically need to add some custom styling. And we chose SAS to do that. It's an extension for the CSS language, which allows you to structure your code in a more maintainable and better way. And again, here, to compile your SAS into something understandable by the browser, we use the state-of-the-art latest implementation of SAS. We also have style lint, which is able to lint your style files automatically.
Now what else do you need in a big project? Well, certainly more testing. And as we already are using Node.js, we are using also Cypress for end-to-end testing of your application. This framework allows you to launch your whole application, interact with it, like press buttons, type text, and then verify if it behaved as expected. For example, that some text appeared or a window got opened. So again, this can be used simply by running a function of the package called test end-to-end.
And finally, as a cherry on top, automation. All these tools are useless if you are not actually running them. And if it's not happening automatically, sooner or later, you will probably forget about it. So if you use GitHub, Rhino comes with a working out-of-the-box setup for GitHub Actions. These will run all the linters, unit tests, end-to-end tests for you automatically once you initialize your project.
What Rhino is
All right, so to summarize, what is Rhino? Well, certainly you can think of it as this complete development toolbox with all those things that I've just listed and mentioned. But it's more than that. We call it a framework. And if you know other frameworks for Python or Ruby on Rails, we took a slightly different angle here. While you do get the project structure, packages to use, and basic structure for your application, we also have all these tools around it for ensuring the quality of your code. So we can think of Rhino as a framework, but for the whole development process.
Then Rhino is certainly the absolute way to do things. It is an opinionated framework based on years of experience that we have in building Shiny applications. It is not the only way to do things, but it is the way that we believe in and that we recommend.
And finally, Rhino is great for enterprise. While you can certainly use it in your next proof of concept project that you will show to nobody, its benefits really start to shine in organizations when you have this one universal toolbox which everybody can use. It really can bring your productivity to a new level.
While you can certainly use it in your next proof of concept project that you will show to nobody, its benefits really start to shine in organizations when you have this one universal toolbox which everybody can use.
So I hope this got you a bit interested in Rhino, perhaps maybe even somewhat excited. So if that's the case, all you need to do is to go to our website. It contains an extensive documentation for the package, as we believe it is an essential part of a framework like this. So thank you for listening, and I encourage you to use Rhino in your next project.