Sep 20, 2023

By Luc Perkins

Creating and modifying flakes using the FlakeHub CLI

Last month we at Determinate Systems announced the initial release of FlakeHub, a brand new platform for publishing and exploring Nix flakes, with features like SemVer for flakes and robust search.

Soon thereafter, we released fh, a CLI tool for interacting with FlakeHub. The initial release of fh offered a modest set of capabilities, including the ability to list and search all publicly listed flakes. But recently we've been iterating on the tool in earnest and today we'd like to announce two new features: fh add and fh init, both of which substantially improve the ergonomics of working with flake.nix files.

Try out fh right now:

nix run ""

See the README instructions to install it on your system.

fh add

The fh add command enables you to quickly add new flake inputs to an existing flake. This command, for example, would add Nixpkgs to your flake.nix:

fh add NixOS/nixpkgs

If you specify a flake reference as :org/:project, as in this example, fh infers that you mean a FlakeHub reference and searches to ensure the flake exists. It then adds a reference to the latest version of the flake. The resulting inputs block may look something like this (notice the FlakeHub address and the specific version):

  inputs = {
    nixpkgs.url = "";

    # Other inputs

You can also use fh add to add non-FlakeHub references:

fh add github:DeterminateSystems/nuenv

fh init

Though it's nice to have a convenient way to update flakes that already work, creating new flakes from scratch can be a bit of a chore. I've done it enough times that it's now ingrained in my muscle memory but I don't look forward to it and we at Determinate Systems suspect that no one does. So we added an fh init command to the FlakeHub CLI. All you have to do is run it in the root of a project and 🪄🦄🧚‍♀️ magical things happen 🪄🦄🧚‍♀️:

cd /path/to/your/project
fh init

fh init assumes that you don't yet have a flake.nix at the root of your project (and if you do, it only overwrites it if you explicitly opt for that). Then it looks at the contents of your project and asks you a series of questions about what you want. At the end of that process, it outputs a flake.nix file that you can immediately use in your project. That's it!

Try it in a flake-less project now:

nix run "" -- init

Here's an example fh init flow:

Similar flows are currently available for Go, Java, JavaScript, PHP, Python, Ruby, and Zig. Beyond these language-specific helpers, fh init also enables you to:

As we usually do at DeterminateSystems, we have strong—though hopefully informed—opinions about how things should be, and flakes are, unsurprisingly, no exception to that. Some opinions that we baked into fh init:

But fh init is just a starter. You're always free to customize at will; after all, it's just Nix code!

We should also note here that fh init is different from flake templates and the related nix flake init command. Flake templates essentially copy pre-existing files—including flake.nix files if you want—into your current directory (or a new directory). fh init, conversely, takes the specifics of your project and your desires into account.

More on the way for fh

We're confident that fh add and fh init will polish off some of the rough edges of working with flakes. But we have plans to improve fh init pretty dramatically in the near future, including:

In the meantime, please don't hesitate to provide feedback in the form of issues and pull requests. Or join us on Discord if you just want to chat about FlakeHub.