Dev Environments for anything

The dream

The dream of modifying your local machine configuration based on whatever it is that you are doing is here. No matter if you are changing the Linux Kernel or just writing a small reminder document, nix has got you covered. The only thing you need to do is nix develop ENV_NAME and you are ready to go.

Flake first

I will not give a master class on what flakes are and how to use them; because I do not know yet :). But what I will do is to give an explanation on how I am using them to orchestrate the going in and coming out of specific shell environments. Let me try to explain it through specific dummy example

{
    # Be sure to have some string that describes your flake
    description = "dummy flake";

    # This is where you define all the dependencies
    inputs = {

        # Bring in the packages from nix official source
        nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";

        # Also bring in some special personal dependencies of your own
        dep0.url = "github:GithubUser/nix_envs?dir=dep0";
    };

    # This is where you define what the flake will provide
    outputs = { self, nixpkgs, dep0, ... }:
        let

            # Be sure to define it for your system architecture
            pkgs = import nixpkgs { system = "x86_64-linux"; };
            system = "x86_64-linux";

        in {

            # This is where you tell it to what you want available in your
            # development shell
            devShells.${system}.default = pkgs.mkShell {
                # Include a list of packages from both nixos and your own dep0
                packages = with pkgs [ git ]
                    ++ dep0.devShells.${system}.default.shellPkgs ;

                # Execute any special commands. You can even use the dep0 ones
                shellHook = '' echo "Entering dummy environment" ''
                    + dep0.devShells.${system}.default.shellHook
                ;
            };
        };
}

Dependencies

The URL lines in the inputs section point to a source; they don’t necessarily need to be from github. You have everything that is provided by these “packages” available in your flake. Two things to note: 1. A flake.nix file is expected to reside on the root path of the pointed repository. 2. You can point to a directory within the repo (instead of just the root) with the “?dir=/PATH” suffix.

Shell Environment

I use devShells to do two things 1. Define a set of packages that are available when I enter the environment 2. Define a set of actions that are run when I enter the environment Worth noting here is that you can actually use elements from the “packages” that you have in the input section.

Public is best

When you are using github repositories it has only worked for me when they are public.

Run Flake

You usually put your dummy flake.nix under a directory; let us say it is under “dummy”. Then, to run the flake, you simply do nix develop /path/to/dummy. Then you packages will be available and your shell script defined in the hook will be run. Your environment is now personalized!!! And to get out of it, you simply do an exit and you are back to your base system.

Register Flake

Typing nix develop /PATH/TO/dummy might be a bit too much. Especially when you want to quickly go in and out of these environments. So I do two things: 1. Use an alias -> "alias nd=“nix develop” 2. Register the flake environments locally. Which requires you to copy a list of all your beautiful flakes in the form of a registry template [1] into ~/.config/nix/registry.json.

Self-referencing Nix Env Repo

I like to keep things in one place, so I added everything to one repository [2] and use different directories for different environments. I reference these with the “?dir=PATH” trick.

A word on Locking

A flake.lock file gets generated when I run nix develop. This has the -very enjoyable- consequence of locking the “version”; its more like a git reference hash. Which means that no matter how much I change [2], I will always have the same version of my environment (until I regenerate my register file).

Conclusion

In conclusion, leveraging Nix flakes to manage development environments offers a
powerful and flexible approach to configuring your environments. By structuring
dependencies, defining shell environments, and utilizing registry files, you can
seamlessly switch between customized environments with minimal effort. Whether
you’re modifying the Linux kernel or working on small projects, Nix provides a
consistent and reproducible environment, ensuring that your development process
remains efficient and reliable.

[1] https://raw.githubusercontent.com/Joelgranados/nix_envs/refs/heads/master/registry.tmpl [2] https://github.com/Joelgranados/nix_envs

Unknown's avatar

About joelgranados

I'm fascinated with how technology and science impact our reality and am drawn to leverage them in order to increase the potential of human activity.
This entry was posted in Uncategorized and tagged , , , , , , , , , , . Bookmark the permalink.

Leave a comment