# 4 Introduction to {golem}

The golem (Fay et al. 2021) package is a framework for building production-grade shiny applications. Many of the patterns and methodologies described in this book are linked to golem and packages from the golemverse. Of course, all the advice developed in this book will still be valid even if you do not plan to use golem.

We have quickly introduced golem in the last chapter, and we will come back to this package many times in the following chapters. Let’s start with an introduction to this package. Note that the version used at the time of writing this book is 0.3.0.

## 4.1 What is {golem}?

Note: The current version of golem used when writing this book is 0.3.0, and some of the features presented in this book might not be available if you are using an older version, or be a little bit different if you have a newer version. Feel free to browse the package NEWS.

golem is a toolkit for simplifying the creation, development and deployment of a shiny application. It focuses on building applications that will be sent to production, but of course starting with golem from the very beginning is also possible, even recommended: it is easier to start with golem than to refactor your codebase to fit into the framework.

The stable release can be found on CRAN and installed with:

install.packages("golem")

The golem development version can be found on GitHub and installed with:

remotes::install_github("Thinkr-open/golem")

The version of the package used while writing this book is:

packageVersion("golem")
[1] '0.3.0'

The motivation behind golem is that building a proof-of-concept application is easy, but things change when the application becomes larger and more complex, and especially when you need to send that app to production. Until recently there has not been any real framework for building and deploying production-grade shiny apps. This is where golem comes into play: offering shiny developers a toolkit for making a stable, easy-to-maintain, and robust production web application with R. golem has been developed to abstract away the most common engineering tasks (for example, module creation, addition and linking of an external CSS or JavaScript file, etc.), so you can focus on what matters: building the application. Once your application is ready to be deployed, golem guides you through testing and brings tools for deploying to common platforms.

Some things to keep in mind before using golem:

• A golem application is contained inside a package. Knowing how to build a package is heavily recommended. The good news is also that everything you know about package development can be applied to golem.

• A golem app works better if you are working with shiny modules. Knowing how modules work is also recommended but not necessary.

## 4.2 Understanding {golem} app structure

A golem application is an R package. Having an R package architecture is perfectly suited for production-ready programs, as we developed in the previous chapter.

Let’s focus on the architecture of the default golem app, and present the role that each file plays and how you can use (or not use) each of them.

You can create a golem project, here called golex, with RStudio “New project” creation or with command line.

golem::create_golem("golex")

The project will start with this specific architecture:

# Listing the files from the golex project using {fs}
fs::dir_tree("golex")
golex
├── DESCRIPTION
├── NAMESPACE
├── R
│   ├── app_config.R
│   ├── app_server.R
│   ├── app_ui.R
│   └── run_app.R
├── dev
│   ├── 01_start.R
│   ├── 02_dev.R
│   ├── 03_deploy.R
│   └── run_dev.R
├── inst
│   ├── app
│   │   └── www
│   │       └── favicon.ico
│   └── golem-config.yml
└── man
└── run_app.Rd

If you are familiar with building R packages, this structure will look familiar to you. And for a good reason: a golem app IS a package.

### 4.2.1DESCRIPTION and NAMESPACE

The DESCRIPTION and NAMESPACE are standard package files (i.e. they are not golem-specific). In DESCRIPTION, you will add a series of metadata about your package, for example, who wrote the package, what is the package version, what is its goal, who to complain to if things go wrong, and also information about external dependencies, the license, the encoding, and so forth.

This DESCRIPTION file will be filled automatically by the first function you will run in dev/01_start.R, and by other functions from the dev/ scripts. In other words, most of the time you will not interact with it directly, but through wrappers from golem and usethis (Wickham and Bryan 2020b) which are listed in the dev scripts.

The NAMESPACE file is the file you will NEVER edit by hand! It defines how to interact with the rest of the package: what functions to import and from which package and what functions to export, i.e. what functions are available to the user when you do library(golex). This file will be built when running the documenting process in your R package, i.e. when doing devtools::document(), or more specifically in our case golem::document_and_reload(). This process will build the man/ files and fill the NAMESPACE, by scanning the {roxygen} tags in your .R files.

If you want to learn more about these files, here are some resources you can refer to:

### 4.2.2 R/

The R/ folder is the standard folder where you will store all your app functions. When you start your project with golem, this folder is pre-populated with three .R files: app_config.R, app_server.R, app_ui.R and run_app.R.

During the process of building your application, all the core functionalities of your app will be stored in this R/ directory, which is the standard way to store functions when using the R package framework. Note that these files are the “core” features of your application itself, and that other .R files also exists. For example, when you will need to deploy your application on RStudio platforms, golem will create an app.R at the root of your directory.21 The dev/ folder also contains .R scripts, and they are inside this folder as they should not live inside the R/ folder: they are utilitarian files used during development, not core functionalities of your application.

Inside these .R files, contained inside the R/ folder, you will find the content of your modules (the one added with golem::add_modules()) and the utilitarian/business logic functions, built with golem::add_utils() and golem::add_fct().

Note also that this folder must not contain any sub-folders.

#### app_config.R

#' Access files in the current app
#'
#' NOTE: If you manually change your package
#' name in the DESCRIPTION, don't forget to change it here too,
#' and in the config file. For a safer name change mechanism,
#' use the golem::set_golem_name() function.
#'
#' @param ... character vectors, specifying subdirectory
#' and file(s) within your package.
#' The default, none, returns the root of the app.
#'
#' @noRd
app_sys <- function(...){
system.file(..., package = "golex")
}

#' Read App Config
#'
#' @param value Value to retrieve from the config file.
#' @param config GOLEM_CONFIG_ACTIVE value.
#' If unset, R_CONFIG_ACTIVE.  If unset, "default".
#' @param use_parent Logical,
#' scan the parent directory for config file.
#'
#' @noRd
get_golem_config <- function(
value,
config = Sys.getenv(
"GOLEM_CONFIG_ACTIVE",
Sys.getenv(
"R_CONFIG_ACTIVE",
"default"
)
),
use_parent = TRUE
){
config::get(
value = value,
config = config,
# Modify this if your config file is somewhere else:
file = app_sys("golem-config.yml"),
use_parent = use_parent
)
}

The app_config.R file contains internal mechanics for golem, notably for referring to values in the inst/ folder, and to get values from the config file in the inst/ folder. Keep in mind that if ever you need to change the name of your application, you will need to change it inside the DESCRIPTION, but also inside the app_sys() function. To make this process easier, you can use the golem::set_golem_name(), which will perform both these actions, plus setting the name inside the config file.

#### app_server.R

#' The application server-side
#'
#' @param input,output,session Internal parameters for {shiny}.
#'     DO NOT REMOVE.
#' @import shiny
#' @noRd
app_server <- function( input, output, session ) {
# Your application server logic

}

The app_server.R file contains the function for the server logic. If you are familiar with the classic “ui.R/server.R” approach, this function can be seen as a replacement for the content of the function you have in your server.R.

Building a complex shiny application commonly implies using shiny modules. If so, you will be adding there a series of callModule(), the ones you will get on the very bottom of the file created with golem::add_module().

You will also find global elements from your server-logic: top-level reactiveValues(), connections to databases, setting options, and so forth.

#### app_ui.R

#' The application User-Interface
#'
#' @param request Internal parameter for {shiny}.
#'     DO NOT REMOVE.
#' @import shiny
#' @noRd
app_ui <- function(request) {
tagList(
# Leave this function for adding external resources
# Your application UI logic
fluidPage(
h1("golex")
)
)
}

This piece of the app_ui.R is designed to receive the counterpart of what you put in your server. Everything here is to be put after the # Your application UI logic line. Just as with their server counterparts, the UI side of these elements are the ones from the bottom of the file you are creating with golem::add_module().

By default, golem uses a fluidPage(), which is the most commonly used shiny (Chang et al. 2020) template. If ever you want to use navBarPage(), this is where you will define it: replace one with the other, and you will be good to go. You can also define any other template page, for example with an htmlTemplate(). For an example of an application built using an htmlTemplate, please visit engineering-shiny.org/grayscale/, or engineering-shiny.org/golemhtmltemplate/: both these applications are built on top of an external html template.

If you’re tempted to do that, be aware that fluidPage() comes with a series of CSS/JS elements, and if you plan on not using a default shiny *Page() function, you will need to add your own CSS.

#' Add external Resources to the Application
#'
#' This function is internally used to add external
#' resources inside the Shiny application.
#'
#' @import shiny
#' @importFrom golem add_resource_path activate_js
#' @importFrom golem favicon bundle_resources
#' @noRd

'www', app_sys('app/www')
)

tags$head( favicon(), bundle_resources( path = app_sys('app/www'), app_title = 'cloop' ) # Add here other external resources # for example, you can add # shinyalert::useShinyalert() ) } The second part of this file contains the golem_add_external_resources() function, which is used to add, well, external resources. You may have noticed that this function is to be found above in the file, in the app_ui() function. This function is used for linking to external files inside your applications: notably the files you will create with golem::add_css_file() and friends. In golem_add_external_resources(), you can also define a custom resourcesPath. The first line (the one with add_resource_path()) is the one allowing the inst/app/www folder to be mounted and be available at www with your app when you launch it. That link makes it possible for golem to bundle the CSS and JavaScript files automatically. The other part of this function, starting with tags$head, creates a <head> tag for your application. This <head> tag is a pretty standard tag, which is used in HTML to define a series of metadata about your app. The last part of this function, the one with bundle_resources(), links all the CSS and JavaScript files contained in inst/app/www to your application, so you don’t have to link them manually.

### 4.2.5dev/

The dev/ folder is to be used as a notebook for your development process: you will find here a series of functions that can be used throughout your project.

The content of these files are specific to golem here, but the concept of using a script to store all development steps is not restricted to a shiny application: it could easily be done for any package, and this is something we recommend that you do. The functions inside these files are the ones used to do some setup, like usethis::use_mit_license() or usethis::use_vignette("my-analysis"), and add testing infrastructure, like usethis::use_test("my-function") or devtools::check(). You will also find functions to populate the application like golem::add_module("my-module") or golem::add_js_file("my-script"). And finally, there are functions you will need once your application is ready: pkgdown::build_site(), rhub::check_for_cran() or golem::add_dockerfile().

We will come back to these files later in this book when we describe in more depth the golem workflow.

### 4.2.6man/

The man/ folder includes the package documentation. It is a common folder automatically filled when you document your app, notably when running the dev/run_dev.R script and the document_and_reload() function.

Building documentation for a package is a widely documented subject, and if you want to know more about documentation and how to build it, here are some external links: