# 05. Configuration

    library(golem)

## Two Ways to Manage Production vs Development Mode

`{golem}` provides two separate mechanisms for managing production and development modes in your Shiny applications:

1. R Options Approach: Using `options(golem.app.prod = TRUE/FALSE)` which is checked by `app_prod()` and `app_dev()` functions. This approach controls the behavior of `{golem}`’s development-aware utility functions like `cat_dev()`, `print_dev()`, `message_dev()`, and similar tools.

2. Configuration File Approach: Using the `golem-config.yml` file to store configuration values (including an `app_prod` setting) that can be retrieved in your application code using `get_golem_config()`.

Important: These two mechanisms are independent and serve different purposes. The R option controls `{golem}`’s built-in development tools, while the config file provides a flexible way to store and retrieve application-specific settings. This vignette focuses on the configuration file approach.

## About `inst/golem-config.yml`

When you start a new `{golem}` application, you’ll find a file called `golem-config.yml` in the `inst/` folder.

By default, this file contains the name of your app, its version, and the default working directory (which is the root of your package).

This config file is based on the `{config}` format, which allows you to create configuration files for different application contexts. Please refer to this package documentation for more information.

## Setting `golem-config`

Here is what the default config file looks like:

    default:
      golem_name: golex
      golem_version: 0.0.0.9000
      app_prod: no

    production:
      app_prod: yes

    dev:
      golem_wd: !expr golem::pkg_path()

- default/golem_name, default/golem_version, default/app_prod can be used across the whole life of your `{golem}` app: while developing, and also when in production.
- production/app_prod can be used to add elements that are to be used once the app is in production.
- dev/golem_wd is in a `dev` config because the only moment you might reliably use this config is while developing your app. Use the `app_sys()` function if you want to rely on the package path once the app is deployed.

The good news is that if you don’t want/need to use `{config}`, you can safely ignore this file, just leave it where it is: it is used internally by the `{golem}` functions.

These options are globally set with:

    set_golem_options()
    #> Warning: `set_golem_options()` is a development function and should not be
    #> called when {golem} is in production mode (`options('golem.app.prod' = TRUE)`).
    #> ── Setting {golem} options in `golem-config.yml` ───────────────────────────────
    #> Warning: `set_golem_name()` is a development function and should not be called
    #> when {golem} is in production mode (`options('golem.app.prod' = TRUE)`).
    #> ✔ Setting `golem_name` to golex
    #> Warning: `set_golem_wd()` is a development function and should not be called
    #> when {golem} is in production mode (`options('golem.app.prod' = TRUE)`).
    #> ✔ Setting `golem_wd` to golem::pkg_path()
    #> You can change golem working directory with set_golem_wd('path/to/wd')
    #> Warning: `set_golem_version()` is a development function and should not be
    #> called when {golem} is in production mode (`options('golem.app.prod' = TRUE)`).
    #> ✔ Setting `golem_version` to 0.0.0.9000
    #> ✔ Setting `app_prod` to FALSE
    #> ── Setting {usethis} project as `golem_wd` ─────────────────────────────────────
    #> ✔ Setting active project to
    #>   "/private/var/folders/9w/zdlv83ws6csdjnfc5x819gtr0000gn/T/RtmpLcDVDH/golex".

    default:
      golem_name: golex
      golem_version: 0.0.0.9000
      app_prod: no
    production:
      app_prod: yes
    dev:
      golem_wd: !expr golem::pkg_path()

The functions reading the options in this config file are:

    get_golem_name()
    #> [1] "golex"
    get_golem_wd()
    #> [1] "/private/var/folders/9w/zdlv83ws6csdjnfc5x819gtr0000gn/T/RtmpLcDVDH/golex"
    get_golem_version()
    #> [1] "0.0.0.9000"

You can set these with:

    set_golem_name("this")
    set_golem_wd(".")
    set_golem_version("0.0.1")

    default:
      golem_name: golex
      golem_version: 0.0.0.9000
      app_prod: no
    production:
      app_prod: yes
    dev:
      golem_wd: !expr golem::pkg_path()

## Using `golem-config`

If you’re already familiar with the `{config}` package, you can use this file just as any config file.

`{golem}` comes with an `amend_golem_config()` function to add elements to it.

    amend_golem_config(
      key = "where",
      value = "indev"
    )
    #> ✔ Setting `where` to indev
    amend_golem_config(
      key = "where",
      value = "inprod",
      config = "production"
    )
    #> ✔ Setting `where` to inprod

Will result in a `golem-config.yml` file as such:

    default:
      golem_name: golex
      golem_version: 0.0.0.9000
      app_prod: no
      where: indev
    production:
      app_prod: yes
      where: inprod
    dev:
      golem_wd: !expr golem::pkg_path()

## `app_config.R`

In `R/app_config.R`, you’ll find a `get_golem_config()` function that allows you to retrieve config from this config file:

    pkgload::load_all()
    #> ℹ Loading golex
    get_golem_config(
      "where"
    )
    #> [1] "indev"
    get_golem_config(
      "where",
      config = "production"
    )
    #> [1] "inprod"

Or using the env var (default `{config}` behavior):

    Sys.setenv("R_CONFIG_ACTIVE" = "production")
    get_golem_config("where")
    #> [1] "inprod"

## `golem_config` vs `golem_options`

There are two ways to configure golem apps:

- The `golem_opts` in the `run_app()` function
- The `golem-config.yml` file

The main difference between these two is that the `{golem}` options from `run_app()` are meant to be configured during runtime: you’ll be doing `run_app(val = "this")`, whereas the `golem-config` is meant to be used in the backend, and will not be linked to the parameters passed to `run_app()` (even if this is technically possible, this is not the main objective).

The `golem-config.yml` file is also linked to the `R_CONFIG_ACTIVE` environment variable, just as any `{config}` file.

Additionally, the `golem-config.yml` file is shareable across `{golem}` projects (whereas `golem_opts` are application specific), and will be tracked by version control systems.

## Connecting Back to the R Options Approach

As mentioned at the beginning of this vignette, `{golem}` uses two separate mechanisms for production/development configuration. While this vignette has focused on the `golem-config.yml` file, it’s important to understand how this relates to the R options approach.

### The R Options Mechanism

The R option `options(golem.app.prod)` is used by `{golem}`’s development-aware functions:

- `app_prod()` - Returns `TRUE` if the app is in production mode
- `app_dev()` - Returns `TRUE` if the app is in development mode
- Development-only output functions: `cat_dev()`, `print_dev()`, `message_dev()`, `warning_dev()`, `browser_dev()`

These functions check `getOption("golem.app.prod")` directly and do not read from the config file.

### Important: The Two Mechanisms Are Independent

The `app_prod` value in `golem-config.yml` and the `options(golem.app.prod)` R option are not automatically synchronized. They serve different purposes:

- Config file `app_prod`: A persistent configuration value that you can retrieve using `get_golem_config("app_prod")` to use in your own application logic. This value can vary by environment (default, production, dev) using the `R_CONFIG_ACTIVE` environment variable.

- R option `golem.app.prod`: A session-level setting that controls `{golem}`’s built-in development tools. This must be explicitly set in your code or launch configuration (e.g., in Docker CMD or `run_dev.R`).

### Best Practices

- Set the R option explicitly: When deploying to production, ensure you set `options(golem.app.prod = TRUE)` in your app’s launch script or Docker configuration. The `{golem}` Dockerfile templates handle this automatically.

- Use the config file for your app’s logic: If you need environment-specific configuration in your application code (e.g., different API endpoints for dev vs production), use `get_golem_config()` to retrieve values from `golem-config.yml`.

- Keep them in sync if needed: If you want the config file’s `app_prod` setting to match your R option, you’ll need to manage this synchronization in your own code. For example, in your `run_app()` function, you could set the option based on the config value:

    # Example: sync config to R option (optional)
    if (get_golem_config("app_prod")) {
      options(golem.app.prod = TRUE)
    }

## Note for `{golem}` < 0.2.0 users

If you’ve built an app with `{golem}` before the version 0.2.0, this config file doesn’t exist: you’ll be prompted to create it if you update a newer version of `{golem}`.