bslib v0.9.0 brings branded theming to Shiny for R

Unified theming is here for R users!
Author

Garrick Aden-Buie

Published

January 31, 2025

bslib + brand.yml

We are excited to share that with bslib v0.9.0, Shiny for R now supports brand.yml, providing a simple and unified theming experience through a single YAML file!

What is brand.yml?

brand.yml simplifies brand management by consolidating your visual identity—colors, typography, and styling—into a single, easy-to-maintain YAML file. Last year, we launched brand.yml with initial support in Quarto and Shiny for Python, and we’re happy to be bringing brand.yml to R as well.

If you haven’t seen brand.yml in action yet, here’s an example _brand.yml file that includes metadata about the company, its logos, color palette, theme, and the fonts and typographic settings used by the brand.

_brand.yml
meta:
  name: brand.yml
  link: https://posit-dev.github.io/brand-yml

logo: 
  small: brand-yml-icon.svg
  medium: brand-yml-tall.svg
  large: brand-yml-wide.svg

color:
  palette:
    orange: "#FF6F20"
    pink: "#FF3D7F"
  primary: orange
  danger: pink

typography:
  fonts:
    - family: Open Sans
      source: google
  base: Open Sans

This one file can be used to maintain consistent branding across your Shiny apps, Quarto projects, and now any R-based project that uses bslib for theming, including shiny, R Markdown, pkgdown, flexdashboard, and more!

Getting Started

bslib is a package maintained by the Shiny team to provide [Bootstrap] styles and components for the R ecosystem. With bslib, using brand.yml to theme your Shiny app is straightforward. To get started, make sure you’ve installed the latest version of bslib:

install.packages("bslib")

Then, create a _brand.yml file in your project directory, either alongside your app.R or in a parent folder of the project containing your app.

If your app uses any of the page functions from bslib like page_sidebar() or page_navbar(), then you’re all set! bslib will automatically find the _brand.yml file and apply it to the app’s theme. For page functions from Shiny—like fluidPage() or navbarPage()—set theme = bs_theme() in the page function.

If you want to use another file name, like acme-brand.yml, or you want to be explicit, you can call bs_theme() and provide the path to the brand.yml file to the brand argument:

ui <- page_sidebar(
  title = "Acme Sales Dashboard",
  theme = bs_theme(brand = "acme-brand.yml"),
  # ... the rest of your app ...
)

Shiny without branding

Brand-themed Shiny

Try brand.yml in Shiny now!

Try brand.yml now with the brand.yml Demo App. You can create and preview your own brand.yml files with this app, and it’s included with bslib so that you can try it locally, too.

# requires shiny v1.8.1 or later
shiny::runExample("brand.yml", package = "bslib")

This app can also be used as a template; see Unified theming with brand.yml on the bslib website for instructions.

brand.yml in R Markdown

The R Markdown ecosystem widely use bslib for theming. Anywhere that theme is passed to bslib, you can use brand.yml, either by placing a file named _brand.yml in the project or by passing a path to your brand.yml file to brand. Note that brand.yml works best with Bootstrap version 5.

For R Markdown, use brand under output.html_document.theme:

report.Rmd
output:
  html_document:
    theme:
      version: 5
      brand: acme-brand.yml

Similarly, in pkgdown, you can use brand under template.bslib:

_pkgdown.yml
template:
  bslib:
    version: 5
    brand: acme-brand.yml

Note that brand isn’t strictly necessary: if you name your brand.yml file _brand.yml, bslib will automatically find it in your project1.

Looking Forward

We look forward to seeing how the community uses this feature and welcome your feedback! You can learn more about brand.yml and its features at the official brand.yml website. Find more specific information about branded and custom theming with bslib at the bslib website, or learn about unified branding across Posit tools with brand.yml on the Posit blog.

As a final tip, we know that writing YAML isn’t everyone’s cup of tea! If you want to enlist the help of a friendly large language model (LLM), we’ve written up a guide to using LLMs to write brand.yml.

Thank you 💙

This post doesn’t cover all of the changes and updates that happened in bslib in this release. To learn more about specific changes in each package, dive into the release notes linked below!

A huge thank you to everyone who contributed pull requests, bug reports and feature requests.

bslib v0.9.0

@al-obrien, @AlbertRapp, @CharlesBordet, @cpsievert, @cscheid, @daattali, @danielloader, @DavZim, @DeepanshKhurana, @dsen6644, @dvg-p4, @eheinzen, @furrrpanda, @gadenbuie, @grcatlin, @ismirsehregal, @jack-davison, @LDSamson, @lmullany, @luisDVA, @lukebandy, @matt-dray, @meztez, @natashanath, @olivroy, @RealKai42, @royfrancis, @see24, @SokolovAnatoliy, @Teebusch, @udurraniAtPresage, and @wulj5.

Footnotes

  1. If you don’t want bslib to use a project-level _brand.yml file, you can use brand: false to disable automatic discovery. Or you can use brand: true to ensure that a project _brand.yml is found. Finally, you could also use brand to provide an entire brand.yml definition in-line!↩︎