The DESCRIPTION file

List project metadata & dependencies in one place

November 2025

Nicolas Casajus

Senior data scientist
@FRB-CESAB    

What is it?




What is it?

The DESCRIPTION file is the main component of an   package describing package metadata

  It can be used with a research compendium to describe project metadata



  Project metadata

Title, description, authors, license, …

What is it?

The DESCRIPTION file is the main component of an   package describing package metadata

  It can be used with a research compendium to describe project metadata



  Project metadata

Title, description, authors, license, …

  Project dependencies

Packages used in the project



  A simple plain text file without extension at the root of the project

  Use the DCF syntax (Debian Control Format), i.e. field: value

Project metadata

  Example of the content of a DESCRIPTION file

Package: projectname
Title: The Title of the Project
Authors@R: c(
    person(
      given = "Jane", 
      family = "Doe", 
      role = "aut",
      email = "jane.doe@mail.me"))
Description: A paragraph providing a full description of 
    the project.
License: GPL (>= 2)
URL: https://github.com/jdoe/projectname/
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.3

Project metadata

  Example of the content of a DESCRIPTION file

Package: projectname
Title: The Title of the Project
Authors@R: c(
    person(
      given = "Jane", 
      family = "Doe", 
      role = "aut",
      email = "jane.doe@mail.me"))
Description: A paragraph providing a full description of 
    the project.
License: GPL (>= 2)
URL: https://github.com/jdoe/projectname/
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.3



  The function add_description() of the package rcompendium can be used to automatically generate a prefilled DESCRIPTION file1

Project dependencies

  Listing packages in a DESCRIPTION file

Package: projectname
Title: The Title of the Project
Authors@R: c(
    person(
      given = "Jane", 
      family = "Doe", 
      role = "aut",
      email = "jane.doe@mail.me"))
Description: A paragraph providing a full description of 
    the project.
License: GPL (>= 2)
URL: https://github.com/jdoe/projectname/
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.3
Depends:
    ggplot2
Imports:
    here,
    readr,
    utils



  Two fields can be used to list dependencies: Depends and Imports



  Let’s talk about library()

Dealing w/ dependencies

  To call a function bar() from the package foo, we usually run library("foo") before using bar()


  Some potential issues


Lack of readability/reproducibility

Where does the function bar() come from?

Conflict between packages

Two different functions w/ the same name come from two different packages and both have been attached. Which of the functions do you use?


library("tidyverse")
## ── Attaching core tidyverse packages ──────────────────────────────────────────────────────────────────────────────────── tidyverse 2.0.0 ## ──
## ✔ dplyr     1.1.2     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.4.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
## ✔ purrr     1.0.1     
## ── Conflicts ────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ## ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package to force all conflicts to become errors

Dealing w/ dependencies

  A solution is to use the Double Colon operator, i.e. foo::bar() instead of library("foo")


Always use the syntax foo::bar() !!!


  Except if you use a package many (many) times (e.g. ggplot2)

Back to the DESCRIPTION file

  Listing packages in a DESCRIPTION file

Package: projectname
Title: The Title of the Project
Authors@R: c(
    person(
      given = "Jane", 
      family = "Doe", 
      role = "aut",
      email = "jane.doe@mail.me"))
Description: A paragraph providing a full description of 
    the project.
License: GPL (>= 2)
URL: https://github.com/jdoe/projectname/
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.3
Depends:
    ggplot2
Imports:
    here,
    readr,
    utils



  List packages in the Imports field if you use foo::bar()



  List packages in the Depends field if you use library(foo)

Ready?




The install_deps() function

  Run install_deps() of the package devtools to install all packages listed in the DESCRIPTION file (Depends & Imports)


# Install packages listed in the DESCRIPTION file ----
devtools::install_deps()



  • All missing packages will be installed
  • New versions will be installed (by default)
  • Already installed packages won’t be reinstalled



Don’t use install.packages() anymore

But wait!




The load_all() function

  Run load_all() of the package devtools to:

  • load packages listed in the Imports field of the DESCRIPTION file
  • load & attach packages listed in the Depends field of the DESCRIPTION file


# Load project ----
devtools::load_all()



Don’t use library() anymore

BUT WAIT!




The load_all() function (2)

  Run load_all() of the package devtools to:

  • source all   functions in the R/ directory


# Load project ----
devtools::load_all()



Don’t use source() anymore

Wrap up

1. Implement   functions in the R/ directory

2. List dependencies in the DESCRIPTION file

3. Run devtools::install_deps() to install required packages

4. Run devtools::load_all() to set up the project (attach packages & source functions)



5. Dont’use install.packages() (use devtools::install_deps())

6. Dont’ use library() (use :: or list package in Depends)

7. Dont’use source() to source functions (use devtools::load_all())



  Have a look at the package rdeps and the function add_deps()