Skip to content

shinychat

0.5.0Package record

Chat UI Component for 'shiny'

6packages dependsuggested by 5
44.8Kdownloads / year
86.1%test coverage
13/13flavors OK

Overview

About

Provides a scrolling chat interface with multiline input, suitable for creating chatbot apps based on Large Language Models (LLMs). Designed to work particularly well with the 'ellmer' R package for calling LLMs.

Changes in 0.5.0

API additions

  • Added chat_server() as the new primary way to wire up server-side chat logic. Pair it with chat_ui() by matching id, e.g. chat_ui("chat") with chat_server("chat", client). It does the same job as chat_mod_server() but runs directly in the caller's session scope rather than creating its own module scope, and it enables many of the features under *New features and improvements* below automatically. chat_mod_server() and chat_mod_ui() are now soft-deprecated in favor of chat_server() and chat_ui(). (#264)
  • Added page_chat() for full-window chat pages with persistent chat navigation, responsive sidebars, and drawers. Register secondary pages with chat_nav_panel(), configure sidebars with chat_sidebar(), and add a drawer with chat_drawer(), controllable from the server via chat_drawer_show(), chat_drawer_update(), chat_drawer_hide(), and chat_drawer_toggle(). Related additions: chat_ui_history() for mounting conversation history outside the chat, a page_chat_theme() baseline theme, and drawer/show_history options on chat_ui(). (#329)
  • The page shell also supports standard bslib programmatic navigation (e.g. bslib::nav_select()), with the active page readable server-side as input$<id>_page.
  • Added slash commands: a typeahead command palette that lets users trigger named shortcuts directly from the chat input (type / to open it). Commands can expand into LLM prompts, trigger server-side side effects (clear chat, open a modal, export transcript), or be handled entirely client-side via the cancelable shiny:chat-slash-command DOM event. Register commands with the slash_command() method of the object returned by chat_server(); its echo parameter controls whether an invocation is recorded as a user message and triggers a loading state. (#239)
  • Added chat_get_greeting() for reading the current greeting (and whether the user dismissed it) from the server, along with a new input$<id>_greeting_dismissed event. Server-set greetings now also survive Shiny bookmarking round-trips. (#254)

New features and improvements

  • chat_server() gets multi-conversation history automatically: a drawer for starting new chats and returning to previous ones, with LLM-generated titles, search, rename, and delete. Conversations are persisted per-user (or a custom scope) via a pluggable store (the default FileConversationStore works out of the box, including on Posit Connect). Customize with history = history_options(...) — e.g. how the active conversation is restored across reloads (browser storage, URL, or Shiny bookmarking) and callbacks to keep app state synced to it — or opt out with history = FALSE. The history object also offers programmatic control, including a reactive conversation ID and an explicit save() method. For apps that can't use chat_server(), wire it up manually with chat_enable_history(). (#266, #307, #328)
  • You can now edit and resend a message after sending it. Editing forks the conversation from that point — the original branch is kept as a sibling, and ‹ 1 / 2 › controls let you switch between versions at any time, including after reloading the page or returning from the history drawer. Requires history to be enabled (the default with chat_server()). (#269)
  • Cancelling an in-progress response is now automatic with chat_server(): the stop button appears by default and cancellation is handled for you. (#264)
  • Added file attachment support: users can upload images, PDFs, and text files alongside their messages. chat_server() enables attachments by default and automatically converts uploads into ellmer Content objects for the model. For non-chat_server() usage, enable with allow_attachments = TRUE (or a MIME allow-list). The maximum combined attachment size defaults to approximately 30 MB and can be configured via the SHINYCHAT_MAX_ATTACHMENT_SIZE environment variable. (#250)
  • When attachments are enabled, input$<id>_user_input is a list of ellmer Content objects (typed text, if present, followed by one object per attachment) rather than a plain string — forward it to a chat method by splicing with !!!, e.g. chat$stream_async(!!!input$<id>_user_input). The last_input reactive returned by chat_server() mirrors this shape.
Show all changes in 0.5.0Hide the rest of the changes in 0.5.0
  • Web search and web fetch responses from ellmer now show their activity and citations directly in the chat. Readers can open a citation beside its claim or use the message-wide Sources pill. ContentCitation@grounded_span links each citation to the answer text it supports. (#280)
  • Citations are powered by a new <shiny-aside> markup convention that any assistant message can use to attach source details to specific claims — useful for custom RAG workflows. See the Asides section in ?chat_append. (#278)
  • Tool call displays have been reworked to be more concise and to intelligently group multiple calls together. By default, calls render as a condensed activity row; expand a group row to see each call, then drill into a call for its full request/result card. (#283)
  • Added tool_result_display(), a constructor for the display object passed as extra = list(display = ...) on an ellmer::ContentToolResult (a bare named list with the same fields still works). New label and value_preview fields (e.g. a filename, and "1,204 rows") are shown in the activity row.
  • A tool's definition title (from its annotations) and its result title (from tool_result_display()) are now shown as-is, without client-side tense conjugation — the old "Running {title}" / "{title} failed" templates are gone. The definition title shows while the call is running; for a single-call row, the result title (if provided) replaces it when the result arrives, and failures are shown via a separate status cue. If a title now reads oddly while running, write it in the present tense (e.g. "Running R code").
  • Control grouping with the tool_grouping parameter of chat_ui(): "tool" (default) groups calls to the same tool within a tool-calling loop, "all" groups every call in the loop together, and "none" shows one activity row per call (thinking or prose starts a new loop). Individual tools can override the chat-level setting with a grouping tool annotation, e.g. tool(..., annotations = tool_annotations(grouping = "all")).
  • Set open_style = "framed" in tool_result_display() to draw a border around an open tool result's header and contents — a better fit for results with a footer or fullscreen toggle. (#331)
  • Fully custom tool-result UI returned from a contents_shinychat() method is now paired with its tool request: while the tool runs it appears in the activity row, and once the result arrives the custom UI renders as standalone output. Custom results are also preserved when preloading or restoring conversations.
  • Added submit_key parameter to chat_ui(): "enter" (default, Enter submits) or "enter+modifier" (Ctrl/Cmd+Enter submits, plain Enter inserts a line break). The input remains editable while a response is streaming — only submission is blocked, not typing. (#251)
  • The send button is easier to customize: a new icon_send parameter on chat_ui() swaps the submit icon, and a data-state attribute exposes the button's current state for styling. (#350)
  • Styling is more customizable via CSS custom properties: the set of public --shiny-chat-* variables has grown to cover the send button, history drawer, page layout, thinking display, and more, and all of them can now be overridden from :root (previously, element-level defaults always won). (#350, #355)
  • Single tildes no longer trigger strikethrough in markdown. Text like (~$1.50) and ~/Documents now renders as literal text; only ~~text~~ produces strikethrough. (#349, #353)

Breaking changes

  • chat_app() now configures its full-window page through page_chat(). Arguments in ... are passed to page_chat() instead of shiny::shinyApp(): use app_options instead of options, bookmark_store instead of enableBookmarking, and compose page_chat() with chat_server() when you need onStart or uiPattern. chat_app() now owns the page layout, so its title, icon, and id configure the page-chat shell. Existing layouts that embed chat should use chat_ui() and chat_server() directly. (#329)
  • The messages parameter is deprecated in favor of the conversation-history feature: chat_ui(messages = ...) now warns, and chat_app(messages = ...) errors when history is enabled (the default). Use greeting for a startup message, chat_append() to replay messages, or history = FALSE if you manage state yourself. (#381)
  • CSS classes and custom properties used by the external-link dialog, thinking display, and tool-result images/PDFs now use the .shiny-chat-* prefix instead of .shinychat-*. Update any custom CSS that targets these identifiers. (#285, #286)

Changes

  • chat_ui() and page_chat() no longer show an assistant icon by default. Pass icon_assistant = TRUE to restore the built-in robot icon, or supply your own icon as before. (#345)
  • chat_ui() now uses a wider default content width on large displays while preserving its existing width on smaller windows. (#364)
  • The dismissible parameter of chat_greeting() has been renamed to persistent with an inverted value. dismissible = FALSE (greeting stays visible) is now persistent = TRUE. The old dismissible argument still works but warns. (#260)

Bug fixes

  • Fixed a security issue where model-authored Markdown could create or escape into shinychat's raw-HTML islands (<shiny-chat-raw-html>), potentially injecting arbitrary HTML into the page. As part of this, output_markdown_stream()/markdown_stream() now track which parts of a mixed value are trusted server-rendered HTML versus untrusted text. (#287, #360)
  • A response that fails before it streams anything (e.g. an exhausted quota, an over-long context, or a dropped connection) is now reported in the chat instead of leaving a loading indicator that never resolves and a locked composer. The chat_server() return also gained last_error, a reactive holding the condition from the most recent failed response, since both a finished and a failed response report "idle" in status. (#304, #314)
  • Fixed output_markdown_stream() permanently stopping following new content after the user scrolled back to the bottom. (#282)
  • Fixed expanding or collapsing a tool result yanking the chat's scroll position away from what you were reading. (#348)
  • chat_app() no longer renders a close button or registers a stopApp() observer when deployed to a server. Both are now gated on rlang::is_interactive(), preventing session crashes in multi-user deployments. (#265)
  • Fixed control-only inputs (the close button, cancel button, and greeting-requested signal) leaking into bookmarked state. (#258, #259)
  • Fixed set_client() failing when the conversation contains an htmlwidget or tagList(). (#362, #369)
  • Fixed suggestion cards and the greeting overflowing the chat container in narrow spaces such as sidebars. (#255)
  • Fixed the copy button on code blocks not working in some embedded contexts. (@thisisnic, #247)

From NEWS.md in the release

Install

Health

CRAN checks
13OK
Slowest check: 3.7 min · r-oldrel-windows-x86_64
Status changes
  • OK13 OK2026-08-04
  • NOTE12 OK, 1 NOTE2026-08-01
  • OK14 OK2026-03-10
Advisories

none known

Documentation

In release 0.5.0
READMEYes · 177 wordsVignettesYes · 2 · dynamicNEWSYes · 100% structured · mentions 0.5.0Citation fileNoWebsiteYes
Help pages
32 (2 internal)includes a package overview page
Examples that run
92%12 run in a plain check (11 of them under a condition) · 1 never run
Exported functions with examples
42%
Documented parameters
97%
Return-value docs
87%
Help pages citing references
0%

Downloads

44.8K
CRAN downloads in the past year
Rank #1,913 · ~123/day · ~3.7K/mo
Daily download trend is not available in this view yet.
2.9K30 days
10K90 days
44.8K1 year
Compare downloads with other packages →
Also on882 r2u7 autocran

Repository

143Stars
30Forks
54Open issues
14Open PRs
30Releases
339Commits
15Commit identities
License file reads as MIT · 339 commits · Last activity 2026-10-16 · +2.9% stars, 30d
Responsiveness
How these are sampled
PRs merged (all time)
89%
Median days to close, 50 most recently updated closed issues
4
Median days to close, 50 most recently updated closed PRs
0

Stars over time

2025-09-28 · 1082026-10-12 · 143
PracticesBeta

7 development-tooling and community-health practices detected across 5 families in the upstream repository

Checks run against github.com/posit-dev/shinychat on 2026-10-11.

Continuous integration (1)
GitHub Actions
Docs source (2)

GitHub Pages site last deployed 2026-09-24 · The repository has a site deploy workflow

Reproducibility and dev environment (1)
Makefile
Automation and maintenance (1)
pre-commit
Show all practicesHide 1 practice
Lint, format, editor (2)
VS CodeRStudio project
How this is detected·Detection ruleset v3 (2026-09-26)
AI coding toolsBeta

This repository shows signs of AI coding tools.

  • Claude Codefirst seen 2026-03-06
    Seen in the repository: CLAUDE.md
    Pull request it wrote: opened by a project member
    Commits: at least 13 crediting it in the message
Shared conventions any agent may read, so they name no particular tool.
Seen in the repository: AGENTS.md
Models named in its commits
  • Claude Opus 4.612 commits · Mar to Apr 2026
  • Claude Sonnet 4.61 commit · Apr 2026
Counts are commits, not lines of code. Commits by a tool's accounts count once across all of its accounts. Commits crediting it are the largest count among its credit lines, a minimum.How this is detected·Detection ruleset v4 (updated 2026-09-27)

Dependencies

Declared dependencies
22 external dependencies (excludes base and recommended)

Installing shinychat adds 43 packages (27 with compiled code, 33 MB of source tarballs). Heaviest: bslib 5.6 MB, promises 3.1 MB, ellmer 3.0 MB.

Depends (0)
none
LinkingTo (0)
none
Enhances (0)
none
Reverse dependencies
6direct
0indirect
Imports 6
Suggested by 5
Depends, Imports or LinkingTo, most downloaded first
Suggests, most downloaded first

People & History

People (5)
Author, Maintainer since 0.2.0 (2025) · added in 0.2.0
Author
Author · added in 0.3.0
Copyright holder, Funder

Previously maintained by Joe Cheng (0.1.1).

Releases (5)

Pick two releases to compare their code metrics.

  • 0.5.0Latest
    record
    2026-09-09 · current release · diff ↗ ·
    added 19 exports
    ContentSlashCommand, ConversationStore, FileConversationStore, chat_attachment, chat_drawer, chat_drawer_hide, chat_drawer_show, chat_drawer_toggle, chat_drawer_update, chat_enable_history, chat_get_greeting, chat_nav_panel, chat_server, chat_sidebar, chat_ui_history, history_options, page_chat, page_chat_theme, tool_result_display
  • 0.4.0
    record
    2026-06-01 · diff ↗ ·
    added 2 exports
    chat_greeting, chat_set_greeting
  • R
    R 4.6.0 released · 2026-04-24
  • 0.3.0
    record
    2025-11-20 · diff ↗ ·
    added 3 exports
    chat_restore, contents_shinychat, update_chat_user_input
  • 0.2.0
    record
    2025-05-16 · diff ↗ ·
    added 6 exports
    chat_app, chat_clear, chat_mod_server, chat_mod_ui, markdown_stream, output_markdown_stream
  • R
    R 4.5.0 released · 2025-04-11
  • 0.1.1
    record
    2024-12-18
  • R
    R 4.4.0 released · 2024-04-24

Package metadata

First published
2024-12-18
Total releases
5 / 2 yrs
License
MIT + file LICENSE OSI
Download size
2.1 MB

Cite

Cite this package

Run in R for the authors' preferred citation:

citation("shinychat")
Aden-Buie, G., Posit Software, PBC, Cheng, J., Schloerke, B., & Sievert, C. (2026). shinychat: Chat UI Component for 'shiny' (Version 0.5.0) [Computer software]. https://doi.org/10.32614/CRAN.package.shinychat

This package has no citation file, so citation() returns this entry built from DESCRIPTION.

Cite the R Observatory

For a number measured here: a download total, a coverage figure, an archival date.

APA

Balamuta, J. J. (2026). R Observatory: Metrics for shinychat version 0.5.0 [Data set]. HJJB, LLC. Data release v2026-10-19. https://doi.org/10.5281/zenodo.21843040

From data release v2026-10-19, which the citation names so these numbers can be found later. More on citing and the projects behind them.

Report a problem with this page →

Privacy choices

These apply to this browser and are stored on this device only. Nothing about your choice is sent to us.

Read the privacy policy