rstudio/shiny: building interactive web apps in R without HTML, CSS or JavaScript
Easy interactive web applications with R
At a glance
- What is it?
- Shiny turns R functions into a live web application through a reactive graph. This review covers the mechanism, the install path from CRAN, where the model breaks down, and what to check before you commit to it.
- Who is it for?
- Adopt shiny when your team already writes R and the analysis is the product: the reactive model fits data work better than hand-written event handlers, and the CRAN install keeps the toolchain short. Skip it when you need a general-purpose web framework, when your app must run without an R process, or when the interface is the hard part rather than the computation.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 35 days ago.
- What is it written in?
- Mainly R, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem shiny solves, and who actually has it
The README states the goal plainly: build interactive web apps in R with no HTML, CSS or JavaScript required. That sentence is doing real work. The person it is written for is an analyst or statistician who has a working R script and now needs other people to change its inputs without editing the script. The alternative is to hand the model to a web developer, describe the parameters, and wait. Shiny compresses that loop: the same R functions that produced a static figure are wired to widgets, and the output updates when an input changes.
The audience is narrow in a useful way. Shiny assumes R is already your language and that the interface is a thin layer over computation. If the interface is the product, a general web framework is the better fit. If the computation is the product and the interface is a control panel, shiny is aimed at you. The README also points to the Shiny User Gallery for examples and to Mastering Shiny and the Shiny Tutorial for learning, noting that the book is currently more up to date with modern features while the tutorial takes a more visual approach to fundamentals.
How the reactive graph decides what reruns
The core mechanism is reactive programming, and the README makes a specific claim about it: compared to event-based programming, reactivity lets Shiny do the minimum amount of work when inputs change, and makes complex MVC logic easier for humans to reason about. That is the whole design in one sentence. You do not register listeners and dispatch events by hand. You declare which inputs an output depends on, and the framework tracks the dependency.
The practical consequence is that an output is a function of inputs, not a callback. When a slider moves, only the outputs whose dependency graph reaches that slider re-execute. The cost is that the graph is implicit: a dependency created inside a branch of an if statement, or one that is only reached on a second run, is a real source of confusion. The README does not document dependency-tracking edge cases here, so treat the reactive model as something to learn deliberately rather than absorb by accident.
Around that core the package ships prebuilt widgets (plots, tables, sliders, dropdowns, date pickers) and a default Bootstrap look that can be customized with the bslib package or bypassed with direct R bindings to HTML, CSS and JavaScript. Modules are the framework for reducing duplication, and the README lists bookmarking application state and generating code to reproduce outputs as separate capabilities.
Install from CRAN and run a first app
The README gives one installation path: the stable version from CRAN. Run this in an R session, and you should see the usual package download and installation output.
install.packages("shiny")Once installed, the README's getting-started example loads the library and launches a prepackaged app. Note the comment in the README: the example launches with the app's source code included, so you can read the code that produced the interface you are looking at.
library(shiny)
# Launches an app, with the app's source code included
runExample("06_tabsets")
# Lists more prepackaged examples
runExample()Calling runExample() with no argument lists the other prepackaged examples, which is the fastest way to see the widget set in a running app rather than in documentation.
The README also documents an Agent Skill shipped inside the package, at system.file("skills", "shiny-for-r", package = "shiny"), intended to help coding agents write idiomatic Shiny for R apps. Agents using btw discover it automatically once shiny is attached. To copy it into a project for Claude Code and other skill-aware tools, the README gives this command:
btw::btw_skill_install_package("shiny")That is a recent addition and worth noting as a sign of where the project is putting effort, though it changes nothing about how an app runs.
Where the reactive model stops being the right tool
The honest limitation is architectural: shiny is an R package, so the application is an R process. Anything you build inherits R's execution model and R's deployment story. The README describes performance tooling (native support for async programming, caching, load testing via shinyloadtest) but the existence of those tools is itself the admission that a single-process R app can be pushed past its comfortable range. A long-running computation in a reactive expression blocks the session unless you take the async route, and the README's link to the async announcement is where that story starts, not a guarantee that it is free.
The second limitation is the one the README advertises as a feature. No HTML, CSS or JavaScript required means the default look is Bootstrap, and customization runs through bslib or through direct bindings. If your design requirements exceed what those layers offer, you are writing web code anyway, in a framework that was not built for it. At that point the argument for shiny over a conventional web stack weakens considerably.
Finally, the README states an R version support policy: the latest release version of R plus the previous four minor release versions. That is a bounded window. Teams pinned to an older R release should check their version against that policy before planning anything.
What to compare against, and the difference that matters
The natural comparison is a general-purpose web framework such as Flask or Django in Python, or Express in JavaScript. The difference is not language preference; it is where the abstraction sits. In a general web framework you write request handlers and manage session state yourself, and the browser is the unit of work. In shiny the unit of work is the reactive expression, and the framework decides when to re-execute it based on tracked dependencies. That is why the README can claim minimum work on input change: the framework knows more about your data flow than a routing table does.
The trade is control. A general framework gives you explicit routing, explicit state, and an ecosystem of middleware that does not depend on an R process. Shiny gives you a smaller surface to write and a dependency graph you did not have to build. If your team's analysis lives in R and the app is a view onto it, the second trade is the better one. If your team's analysis lives in Python and R is a side tool, introducing an R runtime for the interface is a cost with no matching benefit.
Maintenance, release cadence and licence
The repository is not archived, and the last push was on 2026-08-26. Recent releases are v1.14.0 on 2026-06-22, v1.13.0 on 2026-02-24, and v1.12.1 on 2025-12-09, which is a steady cadence of roughly two minor releases a year plus patches. The package.json in the repository carries version 1.14.0-alpha.9000, so the JavaScript side is versioned separately from the R release you install from CRAN.
The upgrade cost sits mostly in that split. The R package bundles front-end assets built with Node (package.json declares node >= 18 and npm >= 10), and the repository also contains a README-npm.md, which suggests the JavaScript tooling is documented for contributors separately. For an application team, the practical upgrade path is the CRAN release, and the NEWS.md file at the repository root is where the changes are listed. The README does not document a rollback procedure, so pinning a version before upgrading is a decision you make on your own.
On licensing: the README states the shiny package as a whole is licensed under the MIT License and points to the LICENSE file. The repository metadata reports the licence as NOASSERTION, which conflicts with the README and with package.json, which also declares MIT. The LICENSE file is the source to read. This is a description of what the files say, not legal advice.
Editorial conclusion
Adopt shiny when your team already writes R and the analysis is the product: the reactive model fits data work better than hand-written event handlers, and the CRAN install keeps the toolchain short. Skip it when you need a general-purpose web framework, when your app must run without an R process, or when the interface is the hard part rather than the computation. Before you start, verify the R version support policy in the README against your installed R, and confirm the package licence text in the LICENSE file rather than trusting the repository metadata, which reports NOASSERTION while the README and package.json both say MIT.
Frequently asked questions
How do I install the shiny package in R?
The README gives one command for the stable version: install.packages("shiny") from CRAN. There is no separate installation step documented for the R package itself.
How do I install shiny in RStudio?
Installation is an R-level operation, not an RStudio-level one: run install.packages("shiny") in an R session. The README does not describe an RStudio-specific installer.
What is shiny in R used for?
The README describes it as a way to build interactive web apps in R without HTML, CSS or JavaScript, using a reactive programming model so outputs react automatically to new user input. It ships widgets for plots, tables, sliders, dropdowns and date pickers.
Which versions of R does shiny support?
The README states that shiny is supported on the latest release version of R plus the previous four minor release versions. It gives the example that if the latest release is 4.3, then 4.3, 4.2, 4.1, 4.0 and 3.6 are supported.
What licence is the shiny package under?
The README says the shiny package as a whole is licensed under the MIT License and points to the LICENSE file, and package.json also declares MIT. The repository metadata reports NOASSERTION, so the LICENSE file is the document to read.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/rstudio-shiny)