The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
htmxr does not replace Shiny — it answers different questions.
Before explaining what htmxr is, it is worth appreciating what Shiny achieved.
Shiny democratized web application development for R users. It handles the browser-to-R communication invisibly, so data scientists can focus entirely on their analysis rather than web infrastructure. What Shiny does remarkably well:
shinydashboard, bslib, DT, plotly…) built specifically for ShinyShiny is the right tool for rich analytical dashboards, scientific interfaces, and internal data exploration tools.
Shiny and htmxr are built on fundamentally different communication models:
| Shiny | htmxr | |
|---|---|---|
| Communication | WebSocket (persistent connection) | HTTP (request/response) |
| Paradigm | Reactive graph | Explicit HTTP requests |
| UI updates | Shiny decides what to reload | You target the DOM precisely |
| State | R session per user | Database or URL |
| Backend | R only | Any HTTP server |
The practical difference: in Shiny, your server reacts. In htmxr, your browser asks.
Shiny maintains one R session per connected user. That session holds all the reactive state — inputs, outputs, intermediate computations — and Shiny decides when to re-evaluate which outputs. This model is powerful and ergonomic, but it means each user consumes a persistent R process.
htmxr apps are largely stateless. Each HTTP request is independent. The server computes something, returns an HTML fragment, and forgets. State lives in the database, the URL, or the client — not in a long-lived R session.
Shiny reloads entire output blocks (uiOutput, renderUI) — sometimes more than strictly necessary. htmx updates exactly the targeted element, nothing more. The result is smoother interfaces, less visual flicker, and a faster perceived experience.
Try the infinite scroll example to see this in practice — 53,940 diamonds loaded progressively, with only the next batch of cards appended to the DOM on each scroll event:
hx_run_example("infinity-scroll")Shiny’s persistent session model means memory consumption scales linearly with the number of connected users. A pool of shared plumber2 workers handles far more concurrent users on the same hardware.
Deployment is standard: nginx, Docker, any VPS, any cloud platform. No Shiny Server license required.
htmxr responses are plain HTML. This means:
An htmxr app can work even when JavaScript is disabled — links and forms remain functional. You can enrich a static HTML page progressively, or add dynamic behaviour to an existing app without rewriting it from scratch.
htmxr generates standard HTML backed by a standard HTTP API. The same plumber2 endpoints that serve your htmxr frontend can be consumed by mobile apps, other services, or scripts in any language — without translation or adaptation.
This is particularly valuable when a proof-of-concept built in R needs to grow into a production system: the business logic stays in R, while other parts of the stack can call the same endpoints.
Choose htmxr when:
Choose Shiny when:
DT, plotly, bslib…)htmxr is not a Shiny replacement. It is a different tool for different problems. If you need reactive, session-based dashboards in R, Shiny is the right choice. If you need scalable, HTTP-native apps that interoperate beyond R, htmxr is the answer.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.