From Shiny to React + D3

Dataviz logo representing a Bar chart.

Shiny is a popular framework for building interactive web applications in R and Python. A few years ago, it's what made me fall in love with data visualization.

This post recreates a Shiny app from the official documentation using modern tools for the web. It describes the process, shows the code, and explains why Shiny is not as useful as it used to be.

Useful links

The Shiny original

I randomly selected one of the first examples in the Shiny documentation. That's only 45 lines of R code for something that is pretty powerful!

The select button filters the dataset and updates the barplot beside it:

gif of the Telephone number Shiny App
Try it live

React version

Now, here is a reproduction using the modern stack for building web applications.

It's a React application that uses D3.js for the graph, Shadcn UI for the button, and Motion for the bar animation.

I used Claude to help me build it. It took me about 20 minutes. I did not track exact timing for each step as for my other speedrun experiment because it was just too fast.

Want to learn how to create web apps like this? You can learn it here!

Data from AT&T (1961) The World's Telephones.

020,000,00040,000,00060,000,0001951195619571958195919601961Number of TelephonesYear

Reproduction of the Shiny app using React and D3.js and Claude.

So, what are the differences?

The reproduced web application above is very minimal. It does not reflect entirely what would happen on a real production app.

But it already highlights some of the drawbacks of Shiny. I've tried to compile a list of features that differ between the two technologies.

Shiny logoShiny
React logoReact + D3
Loading time
🔴
Slow. Requires a server to spin up + load packages. You'll see the dreaded spinner.
🟢
Instant. Static files served from a CDN
Hosting cost
🔴
Paid: needs an R server running 24/7
🟢
Free for static hosting. Cheap for dynamic apps.
Performance
🔴
Each interaction round-trips to the server
R is slow compared to JavaScript
The whole chart needs to be re-built from scratch
🟢
Everything runs client-side → instant feedback
Can update only a fraction of a chart
Animation
🔴
Impossible: a new PNG of the chart is generated on every state update. See how it blinks when you click a button?
🟢
Smooth transitions with Motion / react-spring
UI components
🔴
Basic Bootstrap widgets
🟢
Full access to Shadcn, Radix, Tailwind and billions of other options.
Chart Customization
🟢🔴
Perfect for static charts
Limited to HTML widgets for interactive charts
🟢
Pixel-level control with SVG and D3
Scalability
🔴
Each user needs server resources ($$)
🟢
Scales to millions with no backend
Statistical models
🟢
R excels here. Hardcore stat models run natively with a rich ecosystem of packages.
🟠
Possible via webR, which runs R code in the browser via WebAssembly. Works, but adds complexity and bundle size.
Ease of learning
🟢🟠
Very easy for R users building simple prototypes.
Code becomes complex fast for production-ready results.
🟠
Steeper curve, but AI makes it accessible

Conclusion

This article is not written to say that Shiny is bad or that you should not use it.

Shiny is an awesome piece of technology and what made me fall in love with dataviz. I have deep respect for everyone who made it a thing.

However:

1️⃣ Shiny = Prototypes

Shiny is a wrapper around web tools. It's an additional layer of abstraction. It makes life simpler for quick prototypes, but comes with a cost that is easy to forget for production apps. In my opinion, a lot of Shiny apps should not be made with Shiny.

2️⃣ More AI = less Shiny

With AI becoming more and more powerful, the initial advantage of Shiny is weakening. It no longer takes months to create a data web app, but hours. With code complexity becoming less of an issue, it makes less and less sense to use Shiny.


Please keep using Shiny! But only when it makes sense.

General Knowledge

Contact

👋 Hey, I'm Yan and I'm currently working on this project!

Feedback is welcome ❤️. You can fill an issue on Github, drop me a message on LinkedIn, or even send me an email pasting yan.holtz.data with gmail.com. You can also subscribe to the newsletter to know when I publish more content!