basecoat
Bindings to the basecoat UI component library from R.
Basecoat is a pure tailwind css implementation of shadcn/ui that is the very same design system that powers ricochet.rs. Naturally, we’ve grown quite fond of it.
See all components here.
Installation
install.packages("basecoat")
Or the development version from GitHub:
pak::pak("ricochet-rs/basecoat")
Usage
basecoat is designed as an
htmltools package that
generates raw HTML with opt-in shiny binding.
It works for creating HTML templates or with server-side-rendering (SSR)
with a framework like {plumber2} or
{ambiorix} as well as an opt-in
{shiny} integration.
Each component is an R function that returns htmltools tags. For example creating a card:
library(basecoat)
bc_card(
bc_card_header("Production deploy"),
bc_card_body("All 128 checks pass."),
bc_card_footer(bc_button("View logs"))
)
Examples
Basecoat is a framework agnostic package. Each of these examples illustrate how to use basecoat with a different framework
{htmltools}static html sidebar{shiny}sidebar layout app{plumber2}+{htmxr}for HTMX + Server Side Rendered (SSR) website{nanonext}SSR website
Page Layouts
To help create full page applications, two page layout helps are shipped:
For servers that answer with HTML text rather than tags, bc_page()
writes the whole document as a string.
Develop with an agent
The basecoat package ships with a skill that can be loaded using the
btw R package. You can install the skill via
btw::btw_skill_install_package("basecoat").
If you want to install the skills into Claude code please use:
# project scope
btw::btw_skill_install_package("basecoat", scope = ".claude/skills")
# global scope
btw::btw_skill_install_package("basecoat", scope = "~/.claude/skills")
Shiny integration

{basecoat} ships an optional shiny integration. Because basecoat is
not a shiny-only package, it must be opted into. Do this by calling
bc_shiny_deps() inside your top level UI component (or frankly
anywhere in your UI).
ui <- bc_page_navbar(
bc_shiny_deps()
)
Open an example application file with:
tmp <- tempfile(fileext = ".R")
fp <- system.file("examples", "shiny-inputs.R", package = "basecoat")
file.copy(fp, tmp)
file.edit(tmp)
Custom themes
bc_theme_builder() can be used to launch a small html page to
customize your own theme. Alternatively, you can use the theme
customization in the package
docs to help
bc_theme_builder()
The theme builder can be used with any tweakcn theme.
Copy the example tweakcn theme and paste it into the “Import” button to see how simple it is to customize your theme.
clipr::write_clip(
brio::read_file(
system.file(
"examples/tweakcn-theme.css",
package = "basecoat"
)
)
)


Importing themes
Set your theme by using the bc_deps() function. For SSR or normal
htmltools usage, bc_deps() inside your top level UI component, for
example here, it is bc_page_sidebar(). More on themes is in the
theming
article.
bc_page_sidebar(
bc_deps(
style = "lyra",
theme = system.file(
"examples/tweakcn-theme.css",
package = "basecoat"
)
),
title = "Production",
sidebar = bc_sidebar(id = "sidebar"),
header = bc_theme_switcher(id = "switcher"),
div(
class = "max-w-sm p-4",
bc_card(
bc_card_header(
"Production deploy",
htmltools::p("v1.4.2, 3m 12s"),
bc_card_action(bc_badge("passed"))
),
bc_card_body("All 128 checks green."),
bc_card_footer("Deployed just now.")
)
)
)