Overview
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.
Installation
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'))Usage
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.).
Custom handlers and multiple endpoints
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".
Learn more
- The Getting Started vignette walks through the full handler contract, status semantics, and deployment probe configuration for common platforms.
- A runnable example app ships with the package:
shiny::runApp(system.file("shiny", "hello", package = "shinyhealth"))
