background grid image
Image for post introducing-riff
Sep 6, 2022 by Graham Christensen

Introducing Riff

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:

Terminal window
cd prost
cargo build

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:

Terminal window
riff run cargo build

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:

Terminal window
riff shell
# Enter the Riff shell
cargo run
cargo build
cargo clippy
exit
# Back to your standard shell

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 tiny 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.

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.


Share
Avatar for Graham Christensen
Written by Graham Christensen

Graham is a Nix and Rust developer, with a passion and focus on reliability in the lower levels of the stack. He founded Determinate Systems, Inc to support Nix adoption at your workplace.