Skip to contents

Liquid Glass themes for Shiny. glass_theme() returns a bslib theme with translucent surfaces, backdrop blur, and system typography. Pass it as theme = glass_theme() to fluidPage(), navbarPage(), or other page functions that accept a bslib theme.

Runtime controls (no page reload):

  • Light / Dark / Autoglass_theme_toggle() + update_glass_theme(preset = …), or preset = "auto" to follow the OS
  • Liquid Glass intensity — iOS 27-style Ultra Clear → Tinted via glass_intensity_slider() (and glass_theme(intensity = 0–1))

Documentation · GitHub · Live demos

Liquid Glass intensity

Drop in glass_intensity_slider() for the same continuous control as iOS 27 Settings → Appearance → Liquid Glass. Surfaces update live as you drag from Ultra Clear (0) to Tinted (1) — no page reload.

Liquid Glass intensity slider animating Ultra Clear to Tinted

Liquid Glass intensity slider, lightLiquid Glass intensity slider, dark

Ultra Clear intensityTinted intensityTinted intensity, dark

Glass dashboard, lightGlass dashboard, dark

plotly + gt, lightplotly + gt, dark

Live demos

Public apps on shinyapps.io (free tier may take a few seconds to wake):

App What it shows
Demo + theme toggle Core glass UI + glass_intensity_slider() + Light / Dark / Auto
bslib dashboard page_sidebar, value boxes, plots, DT + intensity in the sidebar
Inputs gallery Built-in Shiny inputs under glass
plotly + gt plotly modebar + gt tables under glass
Olympic medals denser dreamRs-style dashboard (glass port)

Install

# once on CRAN:
install.packages("shinyglass")

# development version:
# remotes::install_github("ericrayanderson/shinyglass")

Quick start

library(shiny)
library(shinyglass)

ui <- fluidPage(
  theme = glass_theme(preset = "auto", intensity = 0.45),
  titlePanel("Liquid Glass"),
  # iOS 27-style Ultra Clear → Tinted (updates live on the client)
  glass_intensity_slider("glass_intensity"),
  # Light / Dark / Auto buttons
  glass_theme_toggle(selected = "auto"),
  sliderInput("n", "Bars", 5, 30, 15),
  plotOutput("plot")
)

server <- function(input, output, session) {
  observe_glass_theme_toggle(input, session)
  # optional: keep server session intensity in sync (client already updates live)
  observe_glass_intensity(input, session, "glass_intensity")
  output$plot <- renderPlot(barplot(seq_len(input$n), col = "#007AFF", border = NA))
}

shinyApp(ui, server)

Set the starting material with glass_theme(intensity = …) (0 Ultra Clear … 1 Tinted), or drive it from the server with update_glass_theme(session, intensity = 0.8).

See the theming article for knobs (intensity, tint, specular, nav_morph) and CSS variables.

# re-deploy live demos (requires rsconnect; installs shinyglass from GitHub):
# remotes::install_github("ericrayanderson/shinyglass")
# Rscript inst/scripts/deploy-shinyapps-demos.R
# Rscript inst/scripts/deploy-shinyapps-demos.R --apps=demo,dashboard,intensity
#
# visual QA (contrast + DT/selectize structure, light+dark matrix):
# Rscript inst/scripts/audit-glass-contrast.R
# see inst/scripts/VISUAL-QA.md

Local examples

shiny::runApp(system.file("examples", "demo-app.R", package = "shinyglass"))
shiny::runApp(system.file("examples", "bslib-dashboard.R", package = "shinyglass"))
shiny::runApp(system.file("examples", "intensity-slider-demo.R", package = "shinyglass"))
shiny::runApp(system.file("examples", "inputs-gallery.R", package = "shinyglass"))
shiny::runApp(system.file("examples", "chrome-kitchen-sink.R", package = "shinyglass"))
# plotly + gt (+ waiter if installed):
# shiny::runApp(system.file("examples", "plotly-gt-demo.R", package = "shinyglass"))

Shiny for Python (experimental)

A parallel package lives under python/ (not on CRAN/PyPI yet). See that README for wheel builds.