shinyhealth provides best practice, production-grade health check endpoints for R Shiny applications with a single function call.
See the package documentation site for full reference and articles.
You can install the development version of shinyhealth from GitHub with:
# install.packages("pak")
pak::pak("jimbrig/shinyhealth")
or via R Universe with:
install.packages('shinyhealth', repos = c('https://jimbrig.r-universe.dev', 'https://cloud.r-project.org'))
Pipe any Shiny app object through add_healthcheck():
library(shiny)
library(shinyhealth)
shinyApp(ui = fluidPage("hello"), server = function(input, output, session) {}) |>
add_healthcheck()
That's it. The app now answers GET /health before any UI rendering, session creation, or authentication occurs:
$ curl -i http://127.0.0.1:8080/health
HTTP/1.1 200 OK
Content-Type: application/health+json
Cache-Control: no-store
{"status":"pass","timestamp":"2026-09-06T23:00:17Z"}
All other requests fall through to your app unchanged -- no uiPattern adjustments required, and it works regardless of how the app was constructed (plain shinyApp(), golem, authentication wrappers like polished, etc.).
Registrations stack, and handlers are plain functions of the request (see health_response() and the handler contract in health_handler_default()):
shinyApp(ui, server) |>
add_healthcheck(path = "/livez") |>
add_healthcheck(path = "/readyz", handler = function(req) {
health_response(
version = "1.0.0",
checks = list(
database = list(status = "pass", latency_ms = 2.3),
upstream_api = list(status = "pass")
)
)
})
Handler errors never break the endpoint -- they are converted into a machine-readable 503 response with status: "fail".
shiny::runApp(system.file("shiny", "hello", package = "shinyhealth"))