{rix}
is an R package that leverages Nix, a package manager focused on
reproducible builds. With Nix, you can create project-specific
environments with a custom version of R, its packages, and all system
dependencies (e.g., GDAL
). Nix ensures full
reproducibility, which is crucial for research and development
projects.
Use cases include running web apps (e.g., Shiny,
{plumber}
APIs) or {targets}
pipelines with a
controlled R environment. Unlike {renv}
, which snapshots
package versions, {rix}
provides an entire ecosystem
snapshot, including system-level dependencies.
While Nix has a steep learning curve, {rix}
renv.lock
files;If you want to watch a 5-Minute video introduction click here.
Nix includes nearly all CRAN and Bioconductor packages, with the
ability to install specific package versions or GitHub snapshots. Nix
also includes Python, Julia (and many of their respective packages) as
well as many, many other tools (up to 120’000 pieces of software as of
writing). Expressions generated by {rix}
point to our fork
of Nixpkgs which provides improved compatibility for older versions of R
and R packages, especially for Apple Silicon computers.
If you have R installed, you can start straight away from your R
session by first installing {rix}
:
install.packages("rix", repos = c(
"https://ropensci.r-universe.dev",
"https://cloud.r-project.org"
))library("rix")
Now try to generate an expression using rix()
:
# Choose the path to your project
# This will create two files: .Rprofile and default.nix
<- "."
path_default_nix
rix(
r_ver = "4.3.3",
r_pkgs = c("dplyr", "ggplot2"),
system_pkgs = NULL,
git_pkgs = NULL,
ide = "code",
project_path = path_default_nix,
overwrite = TRUE,
print = TRUE
)
This will generate two files, default.nix
and
.Rprofile
in project_default_nix
.
default.nix
is the environment definition written in the
Nix programming language, and .Rprofile
prevents conflicts
with library paths from system-installed R versions, offering better
control over your environment and improving isolation of Nix
environments. .Rprofile
is created by
rix_init()
which is called automatically by the main
function, rix()
.
It is also possible to provide a date instead of an R version:
# Choose the path to your project
# This will create two files: .Rprofile and default.nix
<- "."
path_default_nix
rix(
date = "2024-12-14",
r_pkgs = c("dplyr", "ggplot2"),
system_pkgs = NULL,
git_pkgs = NULL,
ide = "code",
project_path = path_default_nix,
overwrite = TRUE,
print = TRUE
)
The table below illustrates this all the different types of environment you can generate:
r_ver or date | Intended use | State of R version | State of CRAN packages | State of Bioconductor packages | State of other packages in Nixpkgs |
---|---|---|---|---|---|
r_ver = “latest-upstream” | Start of new project where versions don’t matter | Current or previous | Outdated (up to 6 months) | Outdated (up to 6 months) | Current at time of generation |
r_ver = “4.4.2” (or other) | Reproducing old project or starting a new project where versions don’t matter |
Same as in r_ver , check available_r()
|
Outdated (up to 2 months if using latest release) | Outdated (up to 2 months if using latest release) | Potentially outdated (up to 12 months) |
date = “2024-12-14” | Reproducing old project or starting a new project using the most recent date |
Current at that date, check available_dates()
|
Current at that date, check available_dates()
|
Current at that date, check available_dates()
|
Potentially outdated (up to 12 months) |
r_ver = “bleeding-edge” | To develop against the latest release of CRAN | Always current | Always current | Always current | Always current |
r_ver = “frozen-edge” | To develop against the latest release of CRAN, but manually manage updates | Current at time of generation | Current at time of generation | Current at time of generation | Current at time of generation |
r_ver = “r-devel” | To develop/test against the development version of R | Development version | Always current | Always current | Always current |
r_ver = “r-devel-bioc-devel” | To develop/test against the development version of R and Bioconductor | Development version | Always current | Development version | Always current |
r_ver = “bioc-devel” | To develop/test against the development version of Bioconductor | Always current | Always current | Development version | Always current |
If you want to benefit from relatively fresh packages and have a
stable environment for production purposes, using a date for
r_ver
is likely your best option.
If you’re already familiar with Nix and {rix}
, install
Nix using the Determinate
Systems installer: (if you’re using WSL, do check out the detailed
installation instructions though):
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
Then, install the cachix
client and configure our
rstats-on-nix
cache; this will install binary versions of
many R packages which will speed up the building process of
environments:
nix-env -iA cachix -f https://cachix.org/api/v1/install
then use the cache:
cachix use rstats-on-nix
You only need to do this once per machine you want to use
{rix}
on. Many thanks to Cachix for sponsoring the
rstats-on-nix
cache!
{rix}
also includes a function called
setup_cachix()
which will configure the cache but it is
recommended to use the cachix
client instead. This is
because setup_cachix()
will not edit the files that require
admin/root privileges and only edit the user-level files. This may not
be enough depending on how you installed Nix. Using the
cachix
client takes care of everything.
You can then use {rix}
to build and enter a Nix-based R
environment:
library(rix)
<- "."
path_default_nix
rix(
r_ver = "4.3.3",
r_pkgs = c("dplyr", "ggplot2"),
system_pkgs = NULL,
git_pkgs = NULL,
ide = "code",
project_path = path_default_nix,
overwrite = TRUE,
print = TRUE
)
To build the environment, call nix_build()
# nix_build() is a wrapper around the command line tool `nix-build`
nix_build(project_path = ".")
If you don’t have R installed, but have the Nix package manager
installed, you can run a temporary terminal session which includes R and
the development version of {rix}
:
nix-shell --expr "$(curl -sl https://raw.githubusercontent.com/ropensci/rix/main/inst/extdata/default.nix)"
You can then create new development environment definitions, build them,
and start using them.
New to {rix}
and Nix? Start by reading the
vignette("a-getting-started")
(online
documentation). to learn how to set up and use Nix smoothly.
Try Nix inside Docker by following this
vignette("z-advanced-topic-using-nix-inside-docker")
vignette.
Docker and {renv} provide robust reproducibility by combining package snapshots with system-level dependencies. However, for long-term reproducibility, Nix offers a simpler approach by bundling everything (R, packages, and dependencies) in a single environment.
Conda is similar to Nix, but Nix offers immutable environments, making it more reliable for preventing accidental changes. Nix also supports nearly all CRAN and Bioconductor packages, which Conda lacks.
Guix, like Nix, focuses on reproducibility, but Nix supports more CRAN/Bioconductor packages and works across Windows, macOS, and Linux.
No, there are other tools that you might want to check out,
especially if you want to set up polyglot environments (even though it
is possible to use {rix}
to set up an environment with R
and Python packages for example).
Take a look at https://devenv.sh/ and https://prefix.dev/ if you want to explore other tools that make using Nix easier!
Ideally, you shouldn’t be using a system-wide installation of R, and instead use dedicated Nix environments for each of your projects.
Start a new project by writing a file called
generate_env.R
and write something like:
library(rix)
path_default_nix <- "."
rix(
r_ver = "4.3.3", # Change to whatever R version you need
r_pkgs = c("dplyr", "ggplot2") # Change to whatever packages you need
system_pkgs = NULL
git_pkgs = NULL,
ide = "code",
project_path = path_default_nix,
overwrite = TRUE,
print = TRUE
)
Then use the following command to bootstrap an enivronment with R and
{rix}
only (from the same directory):
nix-shell --expr "$(curl -sl https://raw.githubusercontent.com/ropensci/rix/main/inst/extdata/default.nix)"
and then simply run Rscript generate_env.R
which will
run the above script, thus generating the project’s
default.nix
. If you need to add packages, open the
generate_env.R
file again, modify it, and run it again, do
not edit the default.nix
directly. Also, commit all the
files to version control to avoid any issues.
Refer to Contributing.md
to learn how to contribute to
the package.
Please note that this package is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.
Thanks to the Nix community for making Nix possible, and thanks to the community of R users on Nix for their work packaging R and CRAN/Bioconductor packages for Nix (in particular Justin Bedő, Rémi Nicole, nviets, Chris Hammill, László Kupcsik, Simon Lackerbauer, MrTarantoga and every other person from the Matrix Nixpkgs R channel).
Finally, thanks to David
Solito for creating {rix}
’s logo!