Get Started
This walkthrough builds, bundles, and installs a small module from nothing, then uses it from R. It assumes {carrier} is on your path (see Installation if it isn’t). Here are following step by step:
1. Scaffold a module
By default, carrier init <module-name> scaffolds the module project containing the pure R codes as the source. Normally, this is how it looks like after the pre-construction of the module:
<module-name>-proj/
├── carrier.toml
├── README.md
└── <module-name>/
├── hello.r
├── add.r
└── __init__.r
Let’s try it with {rmod} for example:
carrier init rmodThis creates rmod-proj/ (the default directory name is <name>-proj). If you don’t want the -proj prefix, then override it with --dir-name.
The generated carrier.toml starts out mostly skeletal — some were pre-filled, and you can edit them once you started making a package. Fill the empty parameters or modify the pre-filled values, e.g. description, authors, license, and any [package_deps] or [module_deps] your module needs. See the carrier.toml reference for the full schema.
The source directory (rmod/) is named after the module by default. If you’d rather use a different directory name, set src in carrier.toml (see Module Structure).
2. Write the module
Everything under rmod/ is just a typical R code. {box} provides Python-like approach for composability of the module. If there’s __init__.py, there’s also __init__.r that serves as the entry point, the module-level equivalent of NAMESPACE but better. Here’s what it looks like under __init__.r
#' @export
box::use(
./hello[hello_world],
./add[add],
)Now, if you plan to attach the namespace under {rmod} module after installing this module, you can attach it according to the following:
box::use(
rmod,
rmod[add, hello_world],
# You can access the submodule under rmod
rmod/add,
rmod/hello,
)3. Packaging/Bundling
This step is similar to R CMD build command or devtools::build(), so this would be more familiar to do. The step to package the {box} module with {carrier} is simple, so start from the project root:
carrier bundle .
#> Bundled 'rmod' (0.1.0) -> /path/to/rmod_0.1.0.tar.gz4. Install it
This is your typical package installation step. There are few ways to install the modules:
If this module is from a tarball local archive:
carrier install ./rmod_0.1.0.tar.gzDirectly from a module directory (carrier bundles it to a temp file first, then installs that):
carrier install .From a GitHub repo, optionally pointing at a subpath:
carrier install gh:username/path/to/rmod-proj
Installing prints where the module landed and the dependency plan carrier worked out from [package_deps] / [module_deps]:
Installed 'rmod' (0.1.0) -> ~/.carrier/modules/rmod
Dependencies:
R packages:
dplyr (*)
Would install R packages (pass --install-deps to proceed):
dplyr (*)
By default, R package dependencies are only planned, not installed. To install the main package dependencies, pass --install-deps to actually fetch and install them from CRAN (the default repo):
carrier install ./rmod_0.1.0.tar.gz --install-depsInstallation of {box} module packages from the local or GitHub requires you to provide the prefixes like ., ./, ../ and suffixes like /. You are not allowed to install the module with just a bare name — it is reserved for modules under remote repositories (this would be the “CRAN” for modules once it is made).
5. Lock dependencies (optional)
Resolving [package_deps] against CRAN can settle on a different version each time you install — a new release published upstream, a different mirror, and so on. To pin what carrier resolved so a later install reproduces it exactly, write a lock file:
carrier lock .This writes carrier.lock next to carrier.toml, listing every resolved package with its exact version and repo. Commit it alongside your module so anyone else installing it gets the same versions.
carrier lock . --update--update ignores any existing lock and re-resolves everything fresh. You’ll use it when you want to deliberately pick up newer versions rather than stay pinned.
Once a lock exists, later installs use it automatically: any package the lock pins installs at that exact version instead of being re-resolved, while anything not in the lock (e.g. a dependency you just added) still resolves fresh.
6. Use it from R
Remember: This is not your traditional CRAN-style packages, so you cannot simply attach it through library() or ::, instead use box::use(), just like the import keyword from Python.
box::use(rmod)
rmod$add(1, 4)
#> 57. Remove it
If you wish to remove {<module-name>} (any packages managed by {carrier}), carrier remove <module-name> is used, akin to pip uninstall.
carrier remove rmodYou’ll be asked to confirm between yes and no. To skip the prompt, supply it with --force.