Package managers like Cargo, pip, and npm are indispensable tools in software development because they quietly handle language-specific dependencies for you. But unfortunately they’re not so great at installing dependencies written in other languages (we call these external dependencies). One of the classic examples is Nokogiri, a widely used XML and HTML parser for Ruby, whose dependency on a C library called libxml2 has caused great consternation for Ruby devs over the years. More recently, external dependencies like OpenSSL and libiconv have proven troublesome for Rust developers.
One half-solution to this problem is to list these external dependencies in the project’s documentation so that developers can install them on their own. Sometimes, projects go a bit beyond that, providing detailed installation instructions for developers in different situations. And occasionally, external dependencies aren’t even mentioned and developers are on their own to provide them, which usually means Googling and StackOverflowing—and wasted time.
Like many of you, we’ve grown weary of half-solutions. We want to be able to
clone a project, cd
in, and have external dependencies quietly taken care of,
and so we built a tool called
Riff that addresses this problem
head on. Today, we at Determinate Systems are
thrilled to announce its initial release.
Introducing Riff
Riff is a tool that we built to help developers write software without having to wrangle dependencies or complicated configuration. It’s built to enable you to clone a project and get to work in seconds. It’s currently available for macOS and standard Linux systems. Upon this initial release, Riff supports Rust projects built with Cargo but we have plans to provide support for other languages, such as Go and the JavaScript ecosystem, in the future.
Riff is powered by Nix, the purely functional language and package manager behind NixOS, Nixpkgs, and many other projects. But don’t worry: we built Riff to solve your problems without requiring you to use, understand, or even care about Nix at all. Riff is powered by Nix but not another Nix tool.
So let’s take a look at Riff in action. Prost is a popular Rust crate that provides a Protocol Buffers implementation for Rust. But on most systems, the build is doomed to fail due to missing external dependencies:
On Linux you get a linker cc not found
error, while on macOS you get library not found for -liconv
errors. Annoying! Even worse, any project that depends
on prost
produces the same error. Now let’s try it with
Riff:
And it works! So what has happened here? Riff has:
- read your project’s
Cargo.toml
, - determined which external dependencies are necessary based on your crate dependency graph,
- used Nix, with zero user input, to install external dependencies in
/nix/store
, and finally - assembled a shell environment that doesn’t interfere with anything else on your system.
The cargo build
command here runs inside that Nix-built shell
environment. In fact, you can enter that environment at any time and run arbitrary commands:
For more on Riff, including instructions for explicitly
specifying
external dependencies in your Cargo.toml
or using Riff with
direnv, see the project
README.
The first time we showed Riff to a user, they were quite surprised and even confused: how could it have been so straightforward? What on Earth quietly happened in the background? That’s the energy we’re going for with Riff: development environments that just work and require, at most, a teensy bit of configuration.
We’re confident that Riff will provide lasting benefits to the Rust ecosystem (and other ecosystems later). Rust is a fantastic language with incredible tools but it has its limits. External dependency problems introduce breakage points into the dependency graphs of many Rust projects. With Riff we hope to cover this “last mile” problem in Rust development and make the entire developer experience more robust.
Find out more about how Determinate Systems is transforming the developer experience around Nix
Future horizons
We’ve kept our ambitions moderate in this initial release, but we still think that Riff will prove to be an indispensable tool for Rust developers—and others in the future. But Nix offers much more power that Riff could potentially tap into, including the ability to generate OCI images, AWS Lambda layers, or even packages for Nix and other package managers. We’re anxious to continue solving thorny, un-fun problems for developers, so stay tuned for more magic from Riff, including support for Go and JavaScript in the near future.
Discussion
If you’d like to discuss Riff with other users, you can join the Discord for Riff.