React UI infrastructure for Shiny. With shinyreact, the Shiny server (Python or R) contains only reactive computation, and the UI is a React client you own — shinyreact provides the bridge between the two and ships zero UI components itself.
One JavaScript bundle backs both languages, so the same React client works identically against an app.py or app.R server.
This repo ships per-language packages:
| Language | Source | Landing page |
|---|---|---|
| Python | pkg-py/ |
pkg-py/README.md |
| R | pkg-r/ |
pkg-r/README.md · pkgdown |
shinyreact implements the ui.tsx pattern: UI defined in a client codebase whose entry conventionally lives in ui.tsx (or App.jsx, or app.js for no-build):
- The Shiny server contains only reactive computation; it bootstraps a static page —
set_react_page()(Express) orpage_react_html()(Core) in Python,page_react_html()in R - A static
www/index.htmlplus your React client serve the UI - Client and server communicate via
useShinyInput/useShinyOutputValue/useShinyMessageHandlerhooks; the server publishes data withreactive_outputand pushes messages withsend_message()
See each package's README for runnable code, and examples/ for working apps.
The bundle re-exports these hooks from @posit/shiny-react:
| Hook | Purpose |
|---|---|
useShinyInput(id, default, opts) |
Read/write a Shiny input — full [value, setValue] |
useShinyInputValue(id) |
Read-only consumer for an input that another component produces |
useSetShinyInput(id, default, opts) |
Write-only producer — registers an input and returns just the setter |
useShinyOutputValue(id, default?) |
Consume arbitrary data sent by reactive_output |
useShinyOutputStatus(id) |
Output lifecycle status — "pending" | "ready" | "recalculating" | "error" |
useShinyMessageHandler(type, fn) |
Handle server-to-client custom messages |
useShinyInitialized() |
Check whether Shiny is connected |
useShinyBusy() |
Whether the Shiny server is currently processing a request |
ImageOutput, ShinyModuleProvider, and ShinyOutput components are exposed the same way. Shared React and ReactDOM instances are available at window.shinyreact.React / window.shinyreact.ReactDOM — externalize to these in your build to avoid duplicate React.
- JS bundle (
js/dist/shinyreact.js): Self-contained IIFE bundling React 19 and vendored@posit/shiny-react, exposing the hook API atwindow.shinyreact. Shared by both language packages. - Python package (
pkg-py/):set_react_page()/page_react_html()page entry points, thereactive_outputrenderer,send_message(), built-in input handlers, and bookmark restore support. - R package (
pkg-r/):page_react_html(),reactive_output(),send_message(), the same input handlers and bookmark support. Same JS bundle as Python.
make setupThis installs Python dependencies (uv sync), JS dependencies (npm install), and pre-commit hooks.
make update-dist # Build JS + copy to pkg-py/www/ and pkg-r/inst/lib/
make py-check # Format check + type check + tests
make py-check-tox # Full matrix: Python 3.10-3.14
make r-check # R format + tests + R CMD check
make js-build-watch # JS watch modeRun make help to see all targets.
