3 min read

Plumber v1.0 Showcase (Part 1)

When I discovered plumber, I fell in love with its versatility. With version 1.0, it is even more versatile and modular than before. Since I had the chance to contribute to the project, I wanted to share some of the new features that made it into this release.

Part 1

New annotation @plumber

New tags were introduced in 1.0. @plumber allows users to interact with the router object during its creation process.

This is quite useful for users who prefers to use plumber lighter annotation syntax. It opens up a range of possibility for debugging, modifying and customizing any aspect of an API. I see it as an alternative to creating a bunch of annotations for special use cases.

Alternatives to Swagger UI

Swagger UI is a great battle tested tool. It is also non trivial to customize as you would have to interface directly with the underlying JS objects. I know of at least two other alternatives that aim to do something similar but offer easier customization. I wanted to make them available to all plumber users so they could have more choices. In 1.0, you can specify a UI to display your API documentation with $setDocs or pr_set_docs.


Redoc is the API documentation engine behind Docker and Discourse. The community edition has great customization support but lacks a built-it API console to try out endpoints at the moment.

This is how you would enable redoc on your plumber API.

Annotation style

#* @plumber
function(pr) {

Programmatic style

pr() %>% pr_set_docs("redoc")

Redoc UI can be customized by passing additional arguments. Some Redoc configuration options are nested so we use nested named R list to define those. Now, let’s build a visual monstrosity to truly grasp the beauty of this engine.

Annotation style


#* @plumber
function(pr) {
    docs = "redoc",
    disableSearch = TRUE,
    expandResponses = "all",
    hideDownloadButton = TRUE,
    theme = list(
      spacing = list(
        unit = 10,
        sectionHorizontal = 2,
        sectionVertical = 4
      colors = list(
        tonalOffset = 0.7
      typography = list(
        fontSize = "26px",
        lineHeight = "1.1em",
        fontWeightBold = "900"
      rightPanel = list(
        backgroundColor = "#00DE9C"
      menu = list(
        backgroundColor = "#4560EA"

#* Imdb says 8.3/10
#* @get /lost
function(msg) {
  paste(msg, "in a bottle")

#* Neither snow nor rain
#* @post /man
function(a = 4, b = 8) {

Masterpiece. I challenge you to do better.

To use it, you will need to install it from meztez/redoc


RapiDoc is my favorite one. The maintainer is friendly and open to pull requests. It is also pretty simple to customize.

This is how you would enable rapidoc on your plumber API.

Annotation style

#* @plumber
function(pr) {

Programmatic style

pr() %>% pr_set_docs("rapidoc")

RapiDoc UI can be customized by passing additional arguments, similar to Redoc. All of the customization attributes are top-level, no need for nested list. Underscores are used in place of hyphens in names so it works nicely in R. Let’s go for peak UI this time.

Annotation style


#* @plumber
function(pr) {
    docs = "rapidoc",
    heading_text = "Knight",
    theme   = "dark",
    bg_color = "#29265D",
    text_color = "#CB9ACA",
    header_color = "#5BA69B",
    primary_color = "#E00925",
    font_size = "largest",
    nav_bg_image = "https://bit.ly/3j2dPw9",
    nav_bg_image_size = "auto",
    nav_bg_image_repeat = "repeat",
    nav_text_color = "#FFFFFF",
    render_style = "read"

#* You're the one I need
#* @get /down
function(lyrics) {
  paste("90s boys band be like", lyrics)

#* Super Sticky Notes
#* @post /it
function(color) {
  paste("This one is", color)

Now this is peak UI.

To use it, you will need to install it from meztez/rapidoc

Both redoc and rapidoc have been submitted to CRAN. It is not much, but it is honest open source.