The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
| Maintainer: | Lluís Revilla, Heather Turner |
| Contact: | lluis.revilla at gmail.com |
| Version: | 2026-10-05 |
| URL: | https://CRAN.R-project.org/view=PackageDevelopment |
| Source: | https://github.com/cran-task-views/PackageDevelopment/ |
| Contributions: | Suggestions and improvements for this task view are very welcome and can be made through issues or pull requests on GitHub or via e-mail to the maintainer address. For further details see the Contributing guide. |
| Citation: | Lluís Revilla, Heather Turner (2026). CRAN Task View: Package Development and Maintenance. Version 2026-10-05. URL https://CRAN.R-project.org/view=PackageDevelopment. |
| Installation: | The packages from this task view can be installed automatically using the ctv package. For example, ctv::install.views("PackageDevelopment", coreOnly = TRUE) installs all the core packages or ctv::update.views("PackageDevelopment") installs all packages that are not yet installed and up-to-date. See the CRAN Task View Initiative for more details. |
The maintainers gratefully acknowledge the initial work on this task view by Roger Bivand.
Packages extend R by providing additional code and/or data. Package development is typically an iterative process, and maintenance involves responding to changes in R and package dependencies.
The essential tools for building and installing packages are provided as R CMD command line tools. Base R provides many relevant functions in utils alongside the tools package, which is dedicated to package development and maintenance. Contributed packages provide alternative or supplementary helper functions.
The definitive reference for R package development is the Writing R Extensions (WRE) manual. The CRAN Repository Policy sets standards on top of this - see the related links below for policies of other repositories.
Contributed packages designed to facilitate package development are not guaranteed to be consistent with WRE or repository policies. Particular caution should be taken when a helper package must be added as a forward dependency: convenience during development can make maintenance harder, both for package authors and for authors of any reverse dependencies.
To assist package developers, this task view collates contributed packages with reference to relevant sections of WRE, highlighting relevant functionality from base/recommended packages before alternative/supplementary tools.
Before starting a new package, it’s worth searching for already available packages, both from a developer’s standpoint (“do not reinvent the wheel”) and from a user’s one (many packages implementing the same/similar procedures can be confusing). If a package addressing the same functionality already exists, you may consider contributing to it instead of starting a new one.
If you are looking for opportunities to contribute, you may find that an existing package needs a new maintainer or there is an open wish for a package that does not yet exist.
The CRAN Team occasionally use the R-package-devel mailing list to ask for maintainers to take on orphaned packages.
The CRAN Search page links to R-focused search tools, facilitating search of package sources, books, task views, support lists, blogs and the internet at large.
utils::RSiteSearch() facilitates search for keywords/phrases in help pages (all the CRAN packages except those for Windows only and some from Bioconductor), package metadata, vignettes or task views, using the search engine at http://search.r-project.org/.
utils::package.skeleton() automates some of the set-up for a new source package. It creates directories, saves functions, data, and R code files provided to appropriate places, and creates skeleton help files and a Read-and-delete-me file describing further steps in packaging.
When initializing a package, it is worth considering how it should be licensed. The CRAN Repository Policy links to a database of licenses acceptable for CRAN.
WRE reference: Package Structure.
create_package() to set up a minimal package structure, along with many utilities to add components, including the use_*_license() functions, where * is replaced by the license name.Rcpp.package.skeleton() from Rcpp extends package.skeleton() to add the components required to use Rcpp for interfacing C or C++ code in R packages. usethis provide similar functionality with the use_c() and use_rcpp() functions.Some contributed packages are analogous to tools in that they provide tools that cut across package development tasks.
Writing R Extensions (WRE) describes the fundamental tasks of package development.
See the “Related Links” section for other guides, including those from Bioconductor and rOpenSci.
load_all() function to simulate installing and reloading the package. Additional functions support generating documentation, testing, checking a package and submitting to CRAN.use_r(), use_data(), use_vignette(), or use_news_md() to add new components, along with functions to support specific packages or workflows, such as use_testthat() or use_git().create() function to initialize a package with the required structure and an infect() function to work with a package initialized another way. The maker repository provides an external Makefile to perform development tasks.roxy.package() function to generate help files, vignettes and package-level documentation (e.g., NEWS and README) in both PDF and HTML; check and build packages, and manage a local package repository. Tasks can be performed individually or in combination.Help pages must be written for exported R objects, and a help page may also be written for the package as a whole. Packages may also include vignettes to give an overview of package functionality or discuss more complex uses. Some contributed packages provide tools to create other types of documentation such as package websites or tutorials.
Source files for help pages use the “R documentation” (Rd) format. utils::prompt() and utils::promptData() may be used to create an Rd template for a function or data set, respectively. tools::checkRd() may be used to validate Rd files, e.g., detecting syntax errors.
WRE reference: Writing R documentation files
roxygenise() function to generate Rd files from comments with specific markup in R source files. When used with Markdown, roxygen2 can greatly reduce the markup required in the documentation source. Several development workflow packages support creating documentation with roxygen2.utils::globalVariables(). This can be used to avoid false positives in the package check when functions in the package call functions that use non-standard evaluation.@dev tag for creating developer documentation for unexported functions; srr adds tags to document adherence to rOpenSci’s standards for software review.The default format for vignettes is Sweave format with special metadata described in WRE. R CMD build will use utils::Sweave() as the default vignette engine to build a vignette. Alternative vignette engines can be specified in the metadata in the form <package>::<engine>.
WRE reference: Writing package vignettes, especially Non-Sweave vignettes
knitr::rmarkdown engine can be used with the rmarkdown::html_vignette() format, which is a lightweight alternative to knitr::html_document(). For mathematics to render offline, the math_method argument of rmarkdown::html_vignette() should be set to "katex" or "r-katex".html_pretty() as an alternative to rmarkdown::html_vignette() that produces lightweight files with fancier themes.R.rsp::rsp engine to use RSP pre-processing directives (e.g., include an external file or use document metadata) and code expressions that allow looping over text with code snippets.tools::CRAN_package_db() returns a data frame with character columns containing most DESCRIPTION metadata for the current packages in the CRAN package repository.
utils::news(package = "pkg") can be used to extract the NEWS for a package and display it in a browser.
NEWS.md file. fledge and autonewsmd generate NEWS.md from git commit messages following conventions specific to each package.JSON-LD format. This is a cross-language metadata standard used by search engines, software repositories etc.CITATION.cff file from package metadata and provide utilities to work with such files, e.g. converting to/from "bibentry" objects (see utils::bibentry()). cffr provides helpers for maintenance via git. CITATION.cff is a cross-language citation file format recognized by software repositories and citation managers.To help promote packages, it has become popular to create hexagon-shaped logos that may be used in package documentation or information files and may be used to create promotional material such as stickers.
Unit tests or regression tests can be added in a tests directory. Tests can be written in R scripts without depending on additional packages, using base::stopifnot() or similar to throw errors when expectations fail. Test scripts are run by R CMD check, with output saved to a corresponding .Rout file. If a corresponding .Rout.save exists in the tests directory, the two output files are compared, with differences being reported but not causing an error.
WRE reference: Package subdirectories
These packages provide some automation and helpers to test code:
assert() and test_pkg() for a simple unit testing interface with minimal dependencies.Testing internet requests can be difficult to do reliably. One can use this book “HTTP testing in R” to take inspiration.
Other packages focused on specific areas:
print() output.A simple way to implement package-specific options is to set global options with a package-specific prefix, but there are several packages that provide more refined and robust management of options.
base::options(), with corresponding environment variables. The options can be set globally or locally (e.g., within a function).brew() and pour() functions, that can be used to store and retrieve package-specific global options, without over-writing any global options of the same name.local_options() function to temporarily change global options within the scope of a function.For simple interactive interfaces, base::readline() can be used to create a basic prompt, while utils::askYesNo() prompts for a set response, by default “Yes” or “No”. utils::menu() and utils::select.list() can provide graphical and console-based selection of items from a list, respectively. utils::txtProgressBar() provides a text progress bar.
tcltk is a base package (not loaded by default) that provides a large set of tools for creating graphical interfaces using Tcl/Tk. Most functions are thin wrappers around the corresponding Tcl and Tk functions.
runApp() or deployed as static web or dynamic websites. See the Web Technologies and Services task view for other frameworks for building R-based web applications.Packages might be addressed to people using a different language and locale. Localization in R uses GNU gettext as described in the notes on Translating R Messages which uses translations stored in PO files.
tools::update_pkg_po() creates or updates the PO template (.pot) files for a package, and updates corresponding PO (.po) files as required. tools::checkPoFile() can be used to check translation files for inconsistently formatted strings.
WRE reference: Internationalization
.pot and .po files, compile the .po files for distribution in a package, and run diagnostics to detect issues, e.g., untranslated messages due to inappropriate R/C code.The standard tools to build and install a package are R CMD build and R CMD INSTALL.
build() function to build R packages and has several utilities to facilitate building packages with compiled code.remotes::install_bioc() can be used to install the development version of a Bioconductor package. ipkg depends on remotes and facilitates installing GitHub packages using a proxy website, if you don’t have access to GitHub.The standard package check is implemented in R CMD check, which should be run on a package built with R CMD build. The check runs examples and tests in the package and the contents of the package are tested in various ways for consistency and portability.
WRE reference: Checking and building packages. Listings of environment variables used in R CMD check may be found the the Tools chapter of the R Internals manual. In the Suggested packages section WRE recommends to run R CMD check both with _R_CHECK_DEPENDS_ONLY_=true and _R_CHECK_SUGGESTS_ONLY_=true, as well as with both of these set to false.
CRAN provide the Winbuilder and macOS builder services for checking on Windows and M1 macOS machines, respectively.
R CMD check on multiple platforms, including Linux, macOS and Windows, via GitHub Actions. The rhub package helps you set up the GitHub Actions on your own GitHub repository, or if you don’t have a GitHub account, you can submit your package to the r-hub2 GitHub organization to use their shared pool of runners.R CMD check from R, returning an "rcmdcheck" object, which you can query and manipulate. The package also provides functions to parse check results from a file or from an URL, including official CRAN check results.See the CI/CD section for information on running package checks automatically.
Package authors may supplement the standard package check with additional checks of code or text quality, using tools in the following sub-sections.
checkUsagePackage() to check all R code in a package for possible problems, e.g., calls not consistent with visible function definitions. checkglobals provides a lightweight alternative to codetools::findGlobals() to check for missing function imports and/or variable definitions without the need for package installation or code execution.lintr::lint_package() can be used to lint R code in a package, including in supplementary files such as tests and vignettes. lintr is combined with linters for other languages by tools including MegaLinter, super-linter and CodeFactor. adaptalint infers the coding style from a package, for linting the same package or a different one. styler automatically reformats code to adhere to a given style guide, eliminating some of the problems lintr can detect.R CMD check and lintr, as well as further checks such a using cyclocomp to check code complexity. Checks can be run individually, e.g., goodpractice::gp(pkg_path, checks = "rcmdcheck_portable_file_names").WRE reference: Checking memory access documents how memory violations and other issues in compiled code such as undefined behaviour can be detected with tools including Valgrind, Address Sanitizer (ASAN) and Undefined Behaviour Sanitizer (UBSAN). These tools required appropriately configured builds of R.
R CMD check with R-devel built with Valgrind, sanitizers, or rchk, along with many other specific configurations of R.utils provides multiple functions for spell-checking portions of packages, including .Rd files ( utils::aspell_package_Rd_files) and vignettes (utils::aspell_package_vignettes) via the general purpose aspell function, which requires a system spell checking library, such as aspell, hunspell, or ispell.
tools provides check_package_urls() and check_package_dois() for checking URLs and DOIs in package metadata and information files.
Using a check service such as Winbuilder or R-hub may reveal a bug in your package that is specific to the computational environment, e.g., the version of R, or the compiler used. The following tools support debugging in such cases.
The CRAN Cookbook is a guide written in collaboration with the CRAN Team that provides “recipes” for solving common issues in package code or documentation found during CRAN (re)-submission checks.
Most packages are developed with long-term use in mind. This requires package developers to keep pace with changes in R, other packages, system tools and environments (e.g. compilers, operating systems) that affect the behaviour of their package. Repositories like CRAN or Bioconductor require packages to meet their latest policies to avoid being archived/deprecated. Issues are typically picked up by a package failing the regular checks run by the repository maintainers, and package authors will be contacted when action is required. It is best if package authors take a proactive approach to maintenance to ensure their package remains useful and available.
Continuous Integration (CI) is the practice of automatically running tests as updates are made to the source code in a code repository. It may be paired with Continuous Delivery/deployment (CD) automating release or deployment of software/software products. Some code hosting platforms have their own CI/CD system, e.g. GitHub Actions or GitLab Pipelines; there are also standalone tools such as CircleCI and Woodpecker.
CI/CD workflows are usually triggered by committing to the main branch of a repository, though other events such as a pull request comment can be used as a trigger. CI/CD pipelines can also be scheduled, which is useful for running R CMD check regularly, to check for issues when a package is not under active development.
check-r-package to run R CMD check. The example workflow check-standard.yaml uses this action to run R CMD check with R-release on Linux, Mac, and Windows, as well as R-devel and R-oldrel on Linux. Other example workflows compute test coverage with covr; build and publish a pkgdown site; create documentation with roxygen2, lint R code with lintr, and enforce style conventions with styler.use_github_action() to facilitate using the example workflows from r-lib/actions on the GitHub repository for a package.use_bioc_github_action() to set up Bioconductor-friendly GitHub actions. The default workflow is equivalent to check-standard.yaml from r-lib/actions, and this can be extended with optional steps such as running tests and building a pkgdown site.use_github_action_pkgcheck() to set up the ropensci-review-tools/pkgcheck-action which will run pkgcheck::pkgcheck() on a package.use_workflow() to set up GitHub Actions for an R package; each step in the workflow can be enabled/disabled as required. Steps include checking a package with Bioc::BiocCheck(), updating badges on the repository README and pushing a Docker container that has RStudio and the package installed to a container registry such as DockerHub.use_gitlab_ci() to set up GitLab CI/CD pipelines. There is a template that runs R CMD check, computes test coverage with covr and then deploys the pkgdown site for a package.R CMD check, and optionally compute test coverage and build a pkgdown site. tic builds on circle, which provides low-level access to the Circle CI API, e.g. to restart builds.R CMD check on an R package with Woodpecker CI.Most packages have forward dependencies that are declared in the Imports or Suggests fields of the package DESCRIPTION. Packages also typically depend on a minimum version of R, due to explicit or implicit use of base R functions (e.g. for compressing data objects).
In time, a package may in turn be imported or suggested by another package, creating a reverse dependency. For CRAN packages, reverse dependencies are listed on the landing pages (of the form https://CRAN.R-project.org/package={PACKAGE}). Package authors should be aware of these packages that may be impacted as their package evolves. Note that CRAN permits dependencies on Bioconductor packages, as well as other repositories specified in the Additional_repositories field of the DESCRIPTION file.
Forward or reverse dependencies may be identified with tools::package_dependencies(), based on a package database like that returned by utils::available.packages(). Dependencies from either CRAN or Bioconductor can be found by setting the repos argument of utils::available.packages() to BiocManager::repositories().
utils::update.packages() is useful for updating dependencies when trying out changes to a package.
tools::check_packages_in_dir() can be used to check the reverse dependencies of a package (or set of packages).
WRE reference: Package Dependencies.
.R or .Rmd files, and to quickly install missing packages declared in a DESCRIPTION file.Remotes in the DESCRIPTION, for packages on CRAN, Bioconductor, and git repositories.usethis::use_revdep() sets up a package to work with revdepcheck.Package authors should communicate changes in their package for the benefit of users and maintainers of reverse dependencies. They should also be vigilant to changes in the functionality, behaviour, or API of any forward dependencies.
utils::sessionInfo is helpful for tracking changes caused by upstream updates; it records the order in which packages are attached or loaded, which can aid debugging when there are namespace conflicts.
install_version() to install a particular version of a package, while dateback can be used to install packages based on a date or date range.pac_timemachine() to get the package version at a certain date and functions to compare the DESCRIPTION or NAMESPACE across versions.session_info() as an alternative to utils::sessionInfo(). Rather than returning an object with full information on loaded or attached packages, session_info() aims to highlight the key details for these packages, including where packages were installed from. However, the order of loading is lost as the packages are recorded alphabetically.WRE is versioned, addressing R-release, R-patched, and R-devel. Changes do occur as R develops and as the software components on which R is built evolve.
The R Blog and the R-devel mailing list can help keep track of developments in R that may affect your package.
The R-announce mailing list announces planned R releases, indicating when it is a good time to test release candidates on critical workflows.
tools::testInstalledPackage can be used to check if an installed package still passes check, while tools::summarize_CRAN_check_status will summarize the CRAN check status for one or more packages.
The R-package-devel mailing list provides help on package development and can help keep up-to-date with best practices.
badge_cran_checks() for adding a badge to your package README.md that either shows a summary or the worst results from the latest CRAN checks.usethis::browse_package() lets you select from URLs in the package DESCRIPTION, which can be a convenient way to find source code repositories of crucial forward dependencies, to track their development.library() to tell you if installed packages are up-to-date when you load them, helping to keep up with changes in forward dependencies.These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.