On the topic of how to write an R package, there are already several well-established tools (e.g., the {devtools} and {usethis} packages) and comprehensive guides (e.g., Writing R Extensions by R Core Team and R packages by Hadley Wickham). But the biggest obstacle to writing one’s first R package isn’t the availability of tools or comprehensive guides on the subject. It’s the perceived difficulty of it. Fortunately, there are several demystifying blog posts on the subject!

One of the first (and probably most famous) posts is by Hilary Parker, who was nice enough to not only provide a timeless guide to writing an R package but also to identify, number, and title the exact steps in the process:

Writing an R package from Scratch by Hilary Parker

  • Step 0: Packages you will need c("devtools", "roxygen")
  • Step 1: Create your package directory create("cats")
  • Step 2: Add functions cat_fun <- function(...)
  • Step 3: Add documentation #' @param
  • Step 4: Process your documentation devtools::document()
  • Step 5: Install! devtools::install()

These steps still hold up today, but like most things related to software development, they don’t incorporate the newest and best tools. For that, you can turn a post by Tomas Westlake, who provided an updated take on Hilary’s initial post, and, thankfully, also followed the aforementioned step-centric format:

Writing an R package from Scratch by Tomas Westlake

  • Step 0: Packages we need c("devtools", "roxygen2", "usethis")
  • Step 1: Creating the package usethis::create_package()
  • Step 2: Adding functions usethis::use_r()
  • Step 3: Adding function documentation devtools::document() and devtools::install()
  • Step 4: Editing your Description use_cc0_license("First Last")
  • Step 5: Add package documentation usethis::use_package_doc()
  • Step 6: Adding a Git repo usethis::use_git()
  • Step 7: Uploading to GitHub usethis::use_github()
  • Step 8: Adding a Readme usethis::use_readme_rmd()
  • Step 9: Adding a logo usethis::use_logo()

In addition to these step-by-step/how-to posts on writing an R package, there is also a fantastic post by Emil Hvitfedt on the additional tasks associated with testing, documenting, and maintaining packages:

usethis workflow for package development by Emil Hvitfedt

  • Before creation available::available()
  • Creating minimal functional package usethis::create_package() usethis::use_git() usethis::use_github()
  • One time modifications usethis::use_mit_license() usethis::use_gpl3_license() usethis::use_apl2_license() usethis::use_cc0_license() usethis::use_readme_rmd() usethis::use_travis() usethis::use_appveyor() usethis::use_coverage(type = c("codecov")) use_testthat() use_spell_check() use_data_raw() use_news_md()
  • Multiple time modifications usr_r() use_test("function_name") use_package("dplyr") use_vignette("How to do this cool analysis")
  • Before every commit (restart, document, check)
  • Before every release use_version()

as well as an excellent bigger-picture post by Maëlle Salmon about what goes into good open-science R packages:

How to develop good R packages (for open science) by Maëlle Salmon

  • Should your package even exist?
  • What should your package contain exactly?
  • What will your package be called?
  • Where should your package live?
  • How to check your package automatically
  • Bring the package to its users and get feedback

As far as going from 0-60 on writing an R package, it’s really tough to improve on these posts.


Step 0: Required packages

Make sure you have the following packages installed:

install.packages(c("devtools", "roxygen2", "usethis", "pkgdown"))

Step 1: Create

Create the package/directory


Make it an R project



Add a license


Add dependencies


Step 3: Function/data

Add some functions and/or data


Make sure to document them, i.e., #' @param

  • Step 4: Documentation usethis::use_package_doc() usethis::use_news_md() usethis::use_readme_rmd() usethis::use_vignette() usethis::use_logo() usethis::use_lifecycle_logo() usethis::use_cran_logo()
  • Step 5: Build devtools::document() devtools::install()
  • Step 6: Tests usethis::use_testthat() usethis::use_test() usethis::use_coverage(type = c("codecov"))
  • Step 7: Continuous-Integration usethis::use_travis() usethis::use_appveyor()
  • Step 8: Website pkgdown::build_site()
  • Step 9: Git/Github usethis::use_git() usethis::use_github()