See the builds concept page for an overview of the different types of builds and how to perform them.Documentation Index
Fetch the complete documentation index at: https://flox.dev/docs/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Nix expression builds are defined by creating files in the.flox/pkgs/ directory of a Flox environment. These expressions are written in the Nix language, which is incredibly powerful and results in truly reproducible builds.
The environment that contains the builds doesn’t need to have any packages installed because all of the build’s dependencies are defined within the expression, but if there are any packages installed then Flox will attempt to produce a build that is compatible with any packages in the “toplevel” package group.
Defining builds
Each build specified in the.flox/pkgs/ directory corresponds to a different package with the name taken from a combination of the path and file names, for example:
| Path | Name |
|---|---|
.flox/pkgs/hello.nix | hello |
.flox/pkgs/hello/default.nix | hello |
.flox/pkgs/hello/how/do/you/do/default.nix | hello.how.do.you.do |
.flox/pkgs directory must be tracked by a Git repository (git added but not necessarily committed) which ensures that unnecessary cache files and secrets don’t end up in your package.
What can you build?
Nix provides a variety of helpers for common builds and language frameworks to help you package your own software: You can also make modifications to existing packages that are already in the Flox Catalog.Example: Distributing a script
To distribute a simple shell script which has a dependency on existing packages:.flox/pkgs/my-ip.nix
bash and curl are available to the package at runtime. It will also automatically add some error handling options (errexit, nounset, pipefail) and validate the script with shellcheck.
Example: Building your own project
To build a Rust project that lives in the same repository as your Flox environment:.flox/pkgs/quotes-app-rust.nix
Cargo.lock file, run cargo build, and package the resulting binary.
Example: Building a third-party project
If there’s an open source Go project that isn’t already available in the Flox Catalog:.flox/pkgs/quotes-app-go.nix
go.mod file, run go build, and package the resulting binary.
Example: Extensions of an existing package
If you want to use VS Code with some pre-installed extensions:.flox/pkgs/vscode-with-extensions.nix
Example: Newer version of an existing package
If the latest version of a package isn’t yet available in the Flox Catalog then you can often just override theversion and src attributes of the existing package:
.flox/pkgs/hello.nix
Example: Patches to an existing package
If you want to apply a patch, such as an unreleased bug fix, to an existing package:.flox/pkgs/hello-shouty/default.nix
default.nix in its own sub-directory so that we can version control the patch as a separate file.
This build also defines tests so they have to be modified too:
./flox/pkgs/hello-shouty/shouty.patch
Example: Vendor an existing package
Typically you would only override specific attributes of an existing package, which allows you to continue benefiting from upstream changes and surface failures if there are any conflicts, but if you want to copy a package to make more fundamental changes or because it’s being removed upstream:hello package in nixpkgs and save the contents to file which can then be modified.
Catalog imports
Nix expression builds can depend on packages provided by external catalogs: remote repositories or FloxHub users that publish reusable packages. Rather than vendoring dependencies or using Nix flake inputs directly, you declare catalogs in.flox/nix-builds.toml and access their packages via the catalogs argument in your expressions.
See Catalog imports for full documentation and examples.
Tips
Generating hashes
Expressions that fetch external dependencies will often specify hashes to ensure that they are reproducible, trusted, and speed up cached steps. The hash should be changed whenever you change asrc or url otherwise the sources may not be fetched again or they will fail the validation check.
If you don’t have a way of verifying the current hash and you trust the source then you can specify an empty string value:
flox build and take the correct value from the error message: