shinygenui

R-CMD-check

shinygenui lets you add generative UI to Shiny apps. As the app developer, you choose a fixed set of UI components and describe the arguments that each component accepts. Together, these components form a catalog. When someone asks a question in the chat panel, the model chooses components from the catalog and adds them to a canvas. It can also update or remove components as the conversation continues.

The package is similar to Vercel’s json-render and Google’s A2UI, but has a much smaller scope. It uses R, Shiny, and the deployment approaches you already use for Shiny apps. You do not need Node, another server, or schemas written by hand.

Installation

# install.packages("pak")
pak::pak("nanxstats/shinygenui")

How it works safely

Example

Here is a complete app with a chat sidebar, a canvas, and a catalog based on mtcars. Start by asking for a plot of mpg against hp and a value box with the average mpg. Then ask the model to color the points by cylinder count. It updates the existing plot in place.

library(shiny)
library(bslib)
library(shinygenui)

ui <- page_sidebar(
  title = "mtcars explorer",
  sidebar = sidebar(width = 380, shinychat::chat_ui("chat", height = "100%")),
  genui_canvas("canvas")
)

server <- function(input, output, session) {
  catalog <- genui_catalog(genui_components_bslib(data = mtcars))
  genui_server(
    "canvas",
    catalog = catalog,
    chat = ellmer::chat_anthropic(), # Any ellmer provider works
    data = reactive(mtcars),
    chat_id = "chat",
    system_prompt = genui_prompt(catalog, context = "The data is mtcars.")
  )
}

shinyApp(ui, server)

The included components have the same interactive behavior as any other Shiny UI. For example, the histogram has a slider for the number of bins. Moving the slider redraws the plot immediately without another request to the model.

You can define your own component with genui_component():

genui_component(
  name = "value_box",
  description = "A box highlighting one summary statistic.",
  args = list(
    title = "Short label above the value.",
    column = ellmer::type_enum(names(mtcars), "Column to summarize.")
  ),
  ui = function(id, args) {
    ...
  }, # Return htmltools tags
  server = function(id, args, data) {
    ...
  } # Optional Shiny module
)

The inst/examples/ directory contains two runnable apps:

shiny::runApp(system.file("examples/01-mtcars-explorer/", package = "shinygenui"))
shiny::runApp(system.file("examples/02-layout/", package = "shinygenui"))

01-mtcars-explorer introduces the basics. 02-layout shows how to group components in rows and rebuild a canvas from its saved history with genui_replay().

Learn more

License

MIT