Package Dev Workflow: Starting a New Package

[This article was first published on Ye Olde R Blog Grogram, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.


  • A basic workflow to set up an R package


Instructions here will rarely be explicit. These workflows are essentially notes for experienced users to help remind them of the minimal steps to complete the task at hand.


  • Strongish familiarity with RStudio, R packages, and R projects
    • R Packages – contains almost all information to get up and running
  • Medium familiarity with git and github
  • Installation of R, R-Studio, devtools, test_that, and associated dependencies
  • Link Travis and Appveyor accounts to github


  • File -> New project -> New directory -> R package -> check create git repository
  • Write functions:
    • Write functions within .R files in /R directory
    • During dev, to interactively work with functions:
      • reinstalled and load package: devtools::load_all() or ctrl-shift-L
    • Add #' @export comment above all functions intended for user
      • ctrl-shift-D or devtools::document() to add function to NAMESPACE
    • External functions:
      • Add package to Imports field of DESCRIPTION using: devtools::use_package("name_of_package")
      • Reference in code as package::function()
      • Best practice – add min version number in DESCRIPTION:

        dplyr (>= 0.7.5),
      • Frequently used external functions
        • To remove requirement to ref with package::
        • Create imports.R file in /R
        • Populate with:

          #' importFrom package function
  • Document ref
    • Add roxygen2 comments above each exported function:

          #' Title (short and descriptive)
          #' Description (slightly longer)
          #' Details (longer description)
          #' @param a description of parameter a
          #' @param b description of parameter b
          #' @return output of function
          #' @export
          #' @examples
          #' # Short example of use
          #' sum(1, 2)
    • (Re-)build documentation: ctrl-shift-D or devtools::document()
    • Helpful tags:

      # Use parameters from other function:
      #' @inheritParams source_function
      # Document in another function (useful for directing 
      # class-specific methods to documentation within generic)
      #' @describeIn source_function
      # Link to other documentation
      ## If in different package
      #' @seealso \code{\link[package]{function}}
      ## If in same package
      #' @seealso \code{\link{function}}
      # Format as code
      #' \code{x}
      # To add additional sections
      #' @section SectionName:
      # Adding a link
      #' \code{\link{Summary}}
      # If you have a family of related functions where every function ]
      # should link to every other function in the family
      #' @family aggregate functions
      # Ordered list
      #' \enumerate{
      #'   \item First item
      #'   \item Second item
      #' }
      # Unordered list
      #' \itemize{
      #'   \item First item
      #'   \item Second item
      #' }
      # Include an example that is not executed when building package
      sum(1, 2)
  • LICENSE: devtools::use_gpl3_license or devtools::use_mit_license
    • Edit as needed
  • README.Rmd ref
    • devtools::use_readme_rmd
    • Must update .md file after each .Rmd file edit: ctrl+shift+k
  • Vignettes ref
    • devtools::use_vignette("vignette-title")
    • Modify vignette as necessary
    • After each modification: devtools::build_vignettes() or ctrl+shift+k
  • Github
    • Create new repository on github with same name as package
    • Copy commands for pushing an existing repo and enter into RStudio terminal
Push commands

Push commands

  • Testing: ref
    • devtools::use_testthat()
    • Create a .R file for each test in projDir/tests/testthat/
    • Populate with unit testing

      # Describe context at top
      # Example rom tidyr
      test_that("basic invocation works", {
        df <- tibble(x = 1:2, y = 1:2, z = 3:4)
        out <- complete(df, x, y)
        expect_equal(nrow(out), 4)
        expect_equal(out$z, c(3, NA, NA, 4))
    • Run tests: devtools::test() or ctrl + shift + T
  • Continuous integration ref
    • Travis:
      • devtools::use_travis()
      • Flip project repo switch on Travis
      • Add badge to README file

        [![Build Status](](
    • AppVeyor:
      • devtools::use_appveyor()
      • Flip project repo switch on AppVeyor
      • Add badge to README file

        [![AppVeyor Build Status](](
  • Checks and cleanup
    • running devtools::check()
    • Consider lintr or formatR to tidy code
      • lintr::lint_package() adds markers to code and allow for manual cleanup

To leave a comment for the author, please follow the link and comment on their blog: Ye Olde R Blog Grogram. offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)