Skip to content

jeff-hykin/xome

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

76 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

icon

Xome ("Zome") brings the power of Nix's home-manager to projects -- meaning fancy customized team-shared shell enviornments that are even more reproducible than nix-shell --pure.

Example Usage

Grab one of the nix-flakes below and run nix develop to see how it works. Read the Notes section to see how to have a good time once its up and running!

1. Super Simple Home

Skip to the next example if you use flake-utils.

Make a flake.nix in the root of your project:

{
    description = "My Project";
    inputs = {
        nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
        home-manager.url = "github:nix-community/home-manager/release-25.05";
        home-manager.inputs.nixpkgs.follows = "nixpkgs";
        xome.url = "github:jeff-hykin/xome";
        xome.inputs.home-manager.follows = "home-manager";
    };
    outputs = { self, nixpkgs, xome, ... }:
        xome.superSimpleMakeHome { inherit nixpkgs; pure = true; } ({pkgs, system, ...}:
            {
                # for home-manager examples, see: https://deepwiki.com/nix-community/home-manager/5-configuration-examples
                # all home-manager options: https://nix-community.github.io/home-manager/options.xhtml
                home.homeDirectory = "/tmp/virtual_homes/my_project1";
                home.stateVersion = "25.05";
                home.packages = [
                    # vital stuff
                    pkgs.coreutils-full
                    pkgs.dash # needed to make "sh"
                    
                    # optional stuff (things you probably want)
                    pkgs.gnugrep
                    pkgs.findutils
                    pkgs.wget
                    pkgs.curl
                    pkgs.unixtools.locale
                    pkgs.unixtools.more
                    pkgs.unixtools.ps
                    pkgs.unixtools.getopt
                    pkgs.unixtools.ifconfig
                    pkgs.unixtools.hostname
                    pkgs.unixtools.ping
                    pkgs.unixtools.hexdump
                    pkgs.unixtools.killall
                    pkgs.unixtools.mount
                    pkgs.unixtools.sysctl
                    pkgs.unixtools.top
                    pkgs.unixtools.umount
                    pkgs.git
                    pkgs.htop
                    pkgs.ripgrep
                ];
                
                # setup zsh with starship
                programs = {
                    home-manager = {
                        enable = true;
                    };
                    zsh = {
                        enable = true;
                        enableCompletion = true;
                        autosuggestion.enable = true;
                        syntaxHighlighting.enable = true;
                        shellAliases.ll = "ls -la";
                        history.size = 100000;
                        # this is kinda like .zshrc
                        initContent = ''
                            # lots of things need "sh"
                            ln -s "$(which dash)" "$HOME/.local/bin/sh" 2>/dev/null
                            
                            # this enables some impure stuff like sudo, comment it out to get FULL purity
                            export PATH="$PATH:/usr/bin/"
                        '';
                    };
                    # fancy prompt
                    starship = {
                        enable = true;
                        enableZshIntegration = true;
                        settings = {
                            character = {
                                success_symbol = "[∫](bold green)";
                                error_symbol = "[∫](bold red)";
                            };
                        };
                    };
                };
            }
        );
}

After that, just run nix develop in the same directory and you'll have a fancy terminal with all the tools you specified!

2. Simple Home

If you use flake utils you probably have something like this:

{
    description = "My Project";
    inputs = {
        nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
        flake-utils.url = "github:numtide/flake-utils";
        xome.url = "github:jeff-hykin/xome";
    };
    outputs = { self, nixpkgs, flake-utils, xome, ... }:
        let
            something = "something";
        in
            flake-utils.lib.eachDefaultSystem (system:
                {
                    packages = { /* your normal stuff */ };
                }
            );
}

You can add Xome like this:

{
    description = "My Project";
    inputs = {
        nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
        flake-utils.url = "github:numtide/flake-utils";
        xome.url = "github:jeff-hykin/xome";
    };
    outputs = { self, nixpkgs, flake-utils, xome, ... }:
        flake-utils.lib.eachDefaultSystem (system:
            let
                pkgs = nixpkgs.legacyPackages.${system};
            in
                {
                    packages = { /* your normal stuff */ };
                    devShells = xome.simpleMakeHomeFor {
                        inherit pkgs;
                        pure = true;
                        commandPassthrough = [ "sudo" "nvim" "code" ]; # e.g. use external nvim instead of nix's
                        # commonly needed for MacOS: [ "sw_vers" "osascript" "otool" "hidutil" "logger" "codesign" ]
                        homeSubpathPassthrough = [ "cache/nix/" ]; # share nix cache between projects
                        homeModule = {
                            # for home-manager examples, see: 
                            # https://deepwiki.com/nix-community/home-manager/5-configuration-examples
                            # all home-manager options: 
                            # https://nix-community.github.io/home-manager/options.xhtml
                            home.homeDirectory = "/tmp/virtual_homes/your_proj_name1";
                            home.stateVersion = "25.11";
                            home.packages = [
                                # vital stuff
                                pkgs.coreutils-full
                                pkgs.dash # needed to make "sh"
                                
                                # optional stuff
                                pkgs.gnugrep
                                pkgs.findutils
                                pkgs.wget
                                pkgs.curl
                                pkgs.unixtools.locale
                                pkgs.unixtools.more
                                pkgs.unixtools.ps
                                pkgs.unixtools.getopt
                                pkgs.unixtools.ifconfig
                                pkgs.unixtools.hostname
                                pkgs.unixtools.ping
                                pkgs.unixtools.hexdump
                                pkgs.unixtools.killall
                                pkgs.unixtools.mount
                                pkgs.unixtools.sysctl
                                pkgs.unixtools.top
                                pkgs.unixtools.umount
                                pkgs.git
                                pkgs.htop
                                pkgs.ripgrep
                            ];
                            
                            programs = {
                                home-manager = {
                                    enable = true;
                                };
                                zsh = {
                                    enable = true;
                                    enableCompletion = true;
                                    autosuggestion.enable = true;
                                    syntaxHighlighting.enable = true;
                                    shellAliases.ll = "ls -la";
                                    history.size = 100000;
                                    # this is kinda like .zshrc
                                    initContent = ''
                                        # lots of things need "sh"
                                        ln -s "$(which dash)" "$HOME/.local/bin/sh" 2>/dev/null
                                        
                                        # this enables some impure stuff like sudo, comment it out to get FULL purity
                                        export PATH="$PATH:/usr/bin/"
                                    '';
                                };
                                starship = {
                                    enable = true;
                                    enableZshIntegration = true;
                                };
                            };
                        }; 
                    };
                }
        );
}

3. Fully Manual Configuration

If you want absolute control, this is the flake template for you:

{
    description = "My Project";
    inputs = {
        flake-utils.url = "github:numtide/flake-utils";
        nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
        home-manager.url = "github:nix-community/home-manager";
        home-manager.inputs.nixpkgs.follows = "nixpkgs";
        xome.url = "github:jeff-hykin/xome";
    };
    outputs = { self, nixpkgs, flake-utils, home-manager, xome, ... }:
        flake-utils.lib.eachSystem flake-utils.lib.allSystems (system:
            let
                pkgs = nixpkgs.legacyPackages.${system};
            in
                {
                    packages = { /* your normal flake stuff*/ };
                    devShells = xome.makeHomeFor {
                        pure = true;
                        envPassthrough = [ "NIX_SSL_CERT_FILE" "TERM" "XOME_REAL_HOME" "XOME_REAL_PATH" "XOME_FAKE_HOME" "XOME_REAL_USER" ];
                        # ^this is the default list. Could add HISTSIZE, EDITOR, etc without loosing much purity
                        commandPassthrough = [ "sudo" "nvim" "code" ]; # e.g. use external nvim instead of nix's
                        # commonly needed for MacOS: [ "osascript" "otool" "hidutil" "logger" "codesign" ]
                        homeSubpathPassthrough = [ "cache/nix/" ];
                        # ^ could also add ".ssh/", "Library/Keychains/", ".pypirc", etc to get credentials symlinked into the fake home
                        home = (home-manager.lib.homeManagerConfiguration
                             {
                                inherit pkgs;
                                modules = [
                                    {
                                        home.username = "default"; # it NEEDS to be "default", it cant actually be 
                                        home.homeDirectory = "/tmp/virtual_homes/xome_simple";
                                        home.stateVersion = "25.11";
                                        home.packages = [
                                            # vital stuff
                                            pkgs.coreutils-full
                                            pkgs.dash # needed to make "sh"
                                            
                                            # optional stuff
                                            pkgs.gnugrep
                                            pkgs.findutils
                                            pkgs.wget
                                            pkgs.curl
                                            pkgs.unixtools.locale
                                            pkgs.unixtools.more
                                            pkgs.unixtools.ps
                                            pkgs.unixtools.getopt
                                            pkgs.unixtools.ifconfig
                                            pkgs.unixtools.hostname
                                            pkgs.unixtools.ping
                                            pkgs.unixtools.hexdump
                                            pkgs.unixtools.killall
                                            pkgs.unixtools.mount
                                            pkgs.unixtools.sysctl
                                            pkgs.unixtools.top
                                            pkgs.unixtools.umount
                                            pkgs.git
                                            pkgs.htop
                                            pkgs.ripgrep
                                        ];
                                        
                                        programs = {
                                            home-manager = {
                                                enable = true;
                                            };
                                            zsh = {
                                                enable = true;
                                                enableCompletion = true;
                                                autosuggestion.enable = true;
                                                syntaxHighlighting.enable = true;
                                                shellAliases.ll = "ls -la";
                                                history.size = 100000;
                                                # this is kinda like .zshrc
                                                initContent = ''
                                                    # lots of things need "sh"
                                                    ln -s "$(which dash)" "$HOME/.local/bin/sh" 2>/dev/null
                                                    
                                                    # if you don't want things to be perfectly pure, enable the next line
                                                    # export PATH="$PATH:/usr/bin/"
                                                '';
                                            };
                                            starship = {
                                                enable = true;
                                                enableZshIntegration = true;
                                            };
                                        };
                                    }
                                ];
                             }
                        );
                    };
                }
        );
}

Notes!

  • Note 1: sys <COMMAND>
    • Xome is pure-by-default, sys helps keep it practial.
    • git push (no git config found, cause its a pure env)
    • sys git push (works, uses your real home)
    • nvim (command not found)
    • sys nvim (uses your system nvim)
    • sudo chmod +x /dev/thing
    • sys sudo chmod +x /dev/thing
    • (Stay tuned for more convenient features)
  • Note 2: Picking a home directory
    • Using /tmp/somewhere/your_proj_name like the examples is fine, but (if it works for your team) a more permanent path will help with startup time/caching. Sidenote, I'm working on a way to support relative paths and faster start times.
  • Note 3: Bulky Examples
    • The examples below are big and fully inlined (one file) for clarity, but pro-tip: yours can be much more sleek! Make a big home config that is exactly how you like (nu shell / fish, colors, aliases, essential packages, etc), put it in a git repo somewhere, then import it as a starter kit for multiple projects. Its really nice to update a home config one place, then nix flake update to pull it into each project.
    • I'll probably add an example of this using home-modules at some point.
    • I'm considering adding multiple profiles (e.g. someone on the team likes zsh and another person likes fish). Open an issue if you want that feature.

How can I do _ ?

1. How can I change home.stateVersion

If you end up with a big error like:

trace: warning: You are using

  Home Manager version 25.11 and
  Nixpkgs version 25.05.

Using mismatched versions is likely to cause errors and unexpected
behavior. It is therefore highly recommended to use a release of Home
Manager that corresponds with your chosen release of Nixpkgs.

If you insist then you can disable this warning by adding

  home.enableNixpkgsReleaseCheck = false;

to your configuration.

The fix is that we need to change the version of home-manager itself (not nixpkgs). E.g. do this:

All three of the following "THIS NUMBER" need to match:

{
    description = "My Project";
    inputs = {
        nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05"; # <- THIS number and
        home-manager.url = "github:nix-community/home-manager/release-25.05"; # <- THIS number and (below)
        home-manager.inputs.nixpkgs.follows = "nixpkgs";
        xome.url = "github:jeff-hykin/xome";
        xome.inputs.home-manager.follows = "home-manager";
    };
    outputs = { self, nixpkgs, xome, ... }:
        xome.superSimpleMakeHome { inherit nixpkgs; pure = true; } ({pkgs, system, ...}:
            {
                /* stuff */
                home.stateVersion = "25.05"; # <- THIS number
                /* stuff */
            }
}

2. How can I use nushell / fish / custom shell

{
    description = "My Project";
    inputs = {
        nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
        home-manager.url = "github:nix-community/home-manager/release-25.05";
        home-manager.inputs.nixpkgs.follows = "nixpkgs";
        xome.url = "github:jeff-hykin/xome";
        xome.inputs.home-manager.follows = "home-manager";
    };
    outputs = { self, nixpkgs, xome, ... }:
        (xome.superSimpleMakeHome
            {
                # add support for whatever shell you want, pkgs will be from the nixpkgs given below
                overrideShell = pkgs: [ "${pkgs.fish}/bin/fish" "--no-globalrcs" ]; 
                    # NOTE: the --no-globalrcs is zsh specific you'll have to find your shell's equivalent argument
                inherit nixpkgs; 
                pure = true; 
            }
            {pkgs, ...}:
                {
                    # for home-manager examples, see: https://deepwiki.com/nix-community/home-manager/5-configuration-examples
                    # all home-manager options: https://nix-community.github.io/home-manager/options.xhtml
                    home.homeDirectory = "/tmp/virtual_homes/xome_simple";
                    home.stateVersion = "25.05";
                    home.packages = [
                        # vital stuff
                        pkgs.coreutils-full
                        pkgs.dash # needed to make "sh"
                    ];
                    
                    programs = {
                        home-manager = {
                            enable = true;
                        };
                        #
                        # Dont forget to enable it down here!
                        #
                        starship = {
                            enable = true;
                        };
                    };
                }
        );
}

About

The power of Nix home-manager inside nix development shells

Resources

Stars

Watchers

Forks

Packages

No packages published