The bslib R package provides tools for creating custom Bootstrap themes directly from R, making it much easier to customize the appearance of Shiny apps & R Markdown documents. At the moment, bslib provides support for Bootstrap 4 and 3 as well as their various Bootswatch themes. An interactive widget is also provided for previewing themes in real time.

Installation

Install the stable release of bslib on CRAN:

Usage with Shiny requires version 1.6 or higher:

Usage with R Markdown requires version 2.7 or higher:

install.packages("rmarkdown")

Overview

Quickly create custom themes

For a quick sense of what bslib enables, call bs_theme_preview(), which launches a demo Shiny app (for a hosted version, see here) with various UI components. On top of the demo app is an interactive widget for changing some of {bslib}’s theming options in real-time. The video below demonstrates how all these various UI components, even 3rd party components like DT::datatable(), are able to update their CSS styles in response to new theming options.

For every interactive theming change, the widget sends R code to the console to replicate the current theme. That theming code can then be copy/pasted for use inside any Shiny app or R Markdown document.

To use this real-time theming widget inside your own Shiny apps, you must first use a bs_theme(), then call bs_themer() inside the server function. Somewhat similarly, for R Markdown documents, you must first use a bs_theme(), then add runtime: shiny to the YAML matter, then finally call bs_themer() in a code chunk.

Shiny usage

To use bslib in your own Shiny app, pass a bs_theme() object to the theme argument of the relevant page layout function, such as navbarPage() or fluidPage():

library(shiny)
ui <- navbarPage(
  theme = bslib::bs_theme(),
  ...
)
shinyApp(ui, function(input, output) {})

R Markdown usage

To use bslib inside your html_document R Markdown document, either provide an R expression (prefixed with !expr) to create a bs_theme() object for the theme parameter:

---
output:
  html_document:
    theme: !expr bslib::bs_theme()
---

Or, pass any of bs_theme()’s basic theming options to theme more directly, like this:

---
output:
  html_document:
    theme:
      version: 4
      bootswatch: minty
---

Basic theming options

The bs_theme() function provides a singular entry-point to bslib’s basic theming options. Here you can choose a Bootstrap version (currently, version = 4 and version = 3 are supported) as well as any Bootswatch theme (e.g., minty):

bs_theme(version = 4, bootswatch = "minty") %>%
  bs_theme_preview()

bs_theme() also allows for customization of main colors & fonts as well as 100s of more specific theming option via Bootstrap Sass variables. When it comes to custom font(s) that may not be available on the end users machine, make sure to leverage helpers such as font_google() to assist with importing font file(s) in an convenient, efficient, and responsible way.

bs_theme(
  bg = "#101010", fg = "#FDF7F7", primary = "#ED79F9", 
  base_font = font_google("Prompt"),
  code_font = font_google("JetBrains Mono")
) %>%
  bs_theme_preview()

Advanced theming

Add more rules

The bs_add_rules() function assists with bundling additional Sass/CSS rules to the final Bootstrap CSS bundle. Here’s an example of adding nes.css, which adds additional styles for things like the mouse cursor (on top of bs_theme()s theming options).

bs_theme(
  bg = "#e5e5e5", fg = "#0d0c0c", primary = "#dd2020",
  base_font = font_google("Press Start 2P"),
  code_font = font_google("Press Start 2P"),
  "font-size-base" = "0.75rem", "enable-rounded" = FALSE
) %>%
  bs_add_rules(
    '@import "https://unpkg.com/nes.css@latest/css/nes.min.css"'
  ) %>% 
  bs_theme_preview()

In the R Markdown case, it’s recommended that additional CSS (or Sass) rules come through the css parameter.

---
output:
  html_document:
    theme: !expr bslib::bs_theme()
    css: my-rules.scss
---

As with bs_add_rules(), these rules can reference Bootstrap Sass variables as well as utilize convenient Sass mixins or functions like color-contrast(), mix(), etc.

Utility Classes

Thanks to Bootstrap’s Utility Classes, you can add or subtract styles on specific elements to handle common UI problems like spacing, border, colors, and more. See here for some useful examples specific to Shiny and R Markdown as well as here for the full list of Bootstrap 4 Utility Classes.

Dynamic theming

The framework behind real-time theming is also available to Shiny app developers through the setCurrentTheme() and getCurrentTheme() session methods. This is useful for implementing a dark mode switch for your app, or more generally, your own custom real-time theming widget.

Developing themable components

Developers of Shiny input and output widgets who wish to make their custom widgets work seamlessly with custom bslib themes, see here.

Frequently Asked Questions

Does {bslib} work with {flexdashboard}?

Yes, but you currently need the development version to use it.

remotes::install_github("rstudio/flexdashboard")

Then you can customize main color and fonts in the same way as the html_document usage (note also that real-time theming also works):

---
output:
  flexdashboard::flex_dashboard:
    theme:
      bg: "#101010"
      fg: "#FDF7F7"
      primary: "#ED79F9"
      base_font: !expr bslib::font_google("Prompt")
      code_font: !expr bslib::font_google("JetBrains Mono")
---

Does {bslib} work with other Rmd output formats?

In general, bslib should work with any output format that passes a theme argument through rmarkdown::html_document (or rmarkdown::html_document_base). For example, if you want to use Bootstrap 4 inside of my_output_format from {mypkg}, then do:

---
output:
  mypkg::my_output_format:
    theme: 
      version: 4
---

That being said, bslib can’t magically fix additional CSS/JS bundled with custom output formats to be compatible with Bootstrap 4 and custom theming, so please let us know about output formats that should work better with bslib, and we’d be happy to work with the output author to improve the situation.

Does {bslib} work with {shinydashboard}?

No, not at the moment. We currently recommend using the {fresh} package to accomplish similar theming with {shinydashboard}. Also, if you want {shinydashboard}-like package build Bootstrap 4, we currently recommend using {bs4Dash}.