MCPcopy Create free account
hub / github.com/dfrankland/envoluntary

github.com/dfrankland/envoluntary @env-hooks-v0.1.4

Chat with this repo
repository ↗ · DeepWiki ↗ · release env-hooks-v0.1.4 ↗ · + Follow
179 symbols 377 edges 25 files 2 documented · 1% updated 9d ago★ 1609 open issues

Browse by type

Functions 136 Types & classes 43
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

envoluntary

Automatic Nix development environments for your shell.

Envoluntary seamlessly loads and unloads Nix development environments based on directory patterns, eliminating the need for per-project .envrc / flake.nix files while giving you centralized control over your development tooling.

This bridges the gap between installing packages declaratively via NixOS / home-manager and defining them for each project being worked in via flake.nix / direnv / nix-direnv. Especially useful when projects don't use Nix!

graph TD
    A["🌍 System-Wide Approach

(NixOS/home-manager)"] -->|Pro: Centralized

Con: Loses project specificity| B["Management Challenge"]
    C["📁 Per-Project Approach

(flake.nix/direnv)"] -->|Pro: Project-specific

Con: Setup burden| B
    B -->|Envoluntary Solution| D["✨ Pattern-Based Centralized

(Best of both worlds)"]
    D --> E["✅ Centralized config

✅ Project-aware

✅ No per-project setup

✅ Works for non-Nix projects"]

Features

  • Pattern-based matching: Define directory patterns once in your config, get automatic environment loading everywhere
  • Flake-native: Built for Nix flakes from the ground up
  • Shell agnostic: Works with bash, zsh, and fish
  • Fast caching: Profiles are cached and only rebuilt when needed
  • Zero per-project setup: No .envrc files to commit or maintain

Quick Start

  1. Install:

bash cargo install envoluntary

Or use via Nix shell

bash nix shell github:dfrankland/envoluntary -c envoluntary --help

  1. Add the shell hook to your .bashrc, .zshrc, or config.fish:

```bash # Bash/Zsh eval "$(envoluntary shell hook bash)" # or zsh

# Fish envoluntary shell hook fish | source ```

Or use via Nix shell

```bash # Bash/Zsh eval "$(nix shell github:dfrankland/envoluntary -c envoluntary shell hook bash)" # or zsh

# Fish nix shell github:dfrankland/envoluntary -c envoluntary shell hook fish | source ```

  1. Configure your environments in ~/.config/envoluntary/config.toml:

```toml [[entries]] pattern = "./projects/my-website(/.)?" flake_reference = "~/nix-dev-shells/nodejs" # Set whether the flake is impure impure = true

[[entries]] # Patterns can match on tilde too pattern = "~/projects/rust-.*" flake_reference = "github:NixOS/templates/30a6f18?dir=rust"

# Adjacent files or directories can be used to narrow pattern matches [[entries]] pattern = "." pattern_adjacent = "./Cargo\.toml" flake_reference = "github:NixOS/templates/30a6f18?dir=rust" ```

  1. Navigate to a matching directory and your environment loads automatically!

Installing with Nix

The envoluntary flake exports a Nix overlay, making it easy to integrate into your own Nix flake.

About the Flake

The flake.nix in this repository is a flake-parts module that:

  • Exports the envoluntary package as its defaultPackage
  • Provides an overlay that makes envoluntary available in your own flakes

Using the Overlay

To use envoluntary in your own flake.nix, follow these steps:

1. Add the input

Add envoluntary to your flake inputs:

{
  description = "Your flake description";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    envoluntary = {
      url = "github:dfrankland/envoluntary";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { self, nixpkgs, envoluntary }:
    # ... rest of your flake
}

2. Apply the overlay

Apply the overlay to your pkgs:

outputs = { self, nixpkgs, envoluntary }:
  let
    system = "x86_64-linux"; # or your system
    pkgs = import nixpkgs {
      inherit system;
      overlays = [ envoluntary.overlays.default ];
    };
  in {
    # Now pkgs.envoluntary is available
  }

3. Use in your environment

You can now use envoluntary in your development shell or system configuration:

devShells.default = pkgs.mkShell {
  buildInputs = [ pkgs.envoluntary ];
};

Using the home-manager Module

The envoluntary flake exports a home-manager module for seamless integration with your home configuration.

Note: The overlay must be applied to your pkgs for this module to work. See the "Using the Overlay" section above.

1. Add the input

Add envoluntary to your flake inputs (if not already added):

{
  description = "Your flake description";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    home-manager = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    envoluntary = {
      url = "github:dfrankland/envoluntary";
      inputs.nixpkgs.follows = "nixpkgs";
      inputs.home-manager.follows = "home-manager";
    };
  };

  outputs = { self, nixpkgs, home-manager, envoluntary }:
    # ... rest of your flake
}

2. Add the module to your home configuration

home-manager.sharedModules = [ envoluntary.homeModules.default ];
home-manager.users.your-username = {
  programs.envoluntary = {
    enable = true;

    # Optional: enable shell integration (all enabled by default)
    enableBashIntegration = true;
    enableZshIntegration = true;
    enableFishIntegration = true;

    # Optional: provide envoluntary configuration
    config = {
      entries = [
        {
          pattern = ".*/projects/my-website(/.*)?";
          flake_reference = "~/nix-dev-shells/nodejs";
          impure = true;
        }
        {
          pattern = "~/projects/rust-.*";
          flake_reference = "github:NixOS/templates/30a6f18?dir=rust";
        }
        {
          pattern = ".*";
          pattern_adjacent = ".*/Cargo\\.toml";
          flake_reference = "github:NixOS/templates/30a6f18?dir=rust";
        }
      ];
    };
  };
};

Using the NixOS Module

The envoluntary flake also exports a NixOS module for system-wide configuration.

Note: The overlay must be applied to your pkgs for this module to work. See the "Using the Overlay" section above.

1. Add the input

Add envoluntary to your flake inputs (if not already added):

{
  description = "Your flake description";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    envoluntary = {
      url = "github:dfrankland/envoluntary";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { self, nixpkgs, envoluntary }:
    # ... rest of your flake
}

2. Add the module to your system configuration

{
  imports = [
    envoluntary.nixosModules.default
  ];

  programs.envoluntary = {
    enable = true;

    # Optional: enable shell integration (all enabled by default)
    enableBashIntegration = true;
    enableZshIntegration = true;
    enableFishIntegration = true;

    # Whether to load envoluntary in nix-shell, nix shell, or nix develop
    # (default: true)
    loadInNixShell = true;

    # Envoluntary configuration
    config = {
      entries = [
        {
          pattern = ".*/projects/my-website(/.*)?";
          flake_reference = "~/nix-dev-shells/nodejs";
          impure = true;
        }
        {
          pattern = "~/projects/rust-.*";
          flake_reference = "github:NixOS/templates/30a6f18?dir=rust";
        }
        {
          pattern = ".*";
          pattern_adjacent = ".*/Cargo\\.toml";
          flake_reference = "github:NixOS/templates/30a6f18?dir=rust";
        }
      ];
    };
  };
}

Configuration

Adding entries

Manually edit your config file:

envoluntary config edit

Or add entries via the CLI:

envoluntary config add-entry ".*/my-project(/.*)?" ./path/to/flake

Testing patterns

See which entries match a given path:

envoluntary config print-matching-entries /home/user/projects/homelab

Flake references

Any valid Nix flake reference works:

  • Paths: ~/my-flakes/devshell or /home/my-user/devshell
  • GitHub repos: github:owner/repo or github:owner/repo/branch
  • Git repos: git+https://example.com/repo.git

See the Nix flake reference documentation for more options.

Advanced Usage

Force profile updates

When your flake changes:

envoluntary shell export bash --force-update | source

Or just cd to a different directory and back—the hook will detect the stale cache.

Override with explicit flakes

Test an environment without modifying your config:

envoluntary shell export bash --flake-references ~/test-flake | source

Debugging

Check which Nix version you're using:

envoluntary shell check-nix-version

Inspect cache locations:

envoluntary shell print-cache-path --flake-reference ~/my-flake

View your config file path:

envoluntary config print-path

Why should you use this?

The problem

Many projects do not use Nix and adding flake.nix to each project can be bothersome.

Additionally, If you use NixOS or home-manager, your system packages are declaratively managed. But when you need project-specific tools, you typically reach for one of these solutions:

  • direnv + nix-direnv: Requires a .envrc file in every project directory
  • Manual nix develop: Forces you to remember to enter shells explicitly
  • Per-project flakes: Scatters your development environment definitions across your filesystem

Each approach has drawbacks: .envrc files become noise in your repositories, manual shells break your workflow, and scattered flakes make environment management inconsistent.

The solution

Envoluntary centralizes your development environment configuration while maintaining automatic activation. Define your patterns once, and every matching directory gets the right environment—no per-project files needed.

Perfect for:

  • Maintaining consistent dev environments across multiple related projects
  • Organizations with standardized tooling per project type
  • Developers who want declarative control without repository clutter
  • Anyone using NixOS/home-manager who wants the same philosophy for dev shells

Not ideal for:

  • Projects where the environment definition should be version-controlled alongside code
  • Shared repositories where other developers need easy access to the same environment
  • One-off projects where you're fine with manual nix develop

Prior Art

Envoluntary stands on the shoulders of giants:

direnv

Similarity: Both tools automatically load environment variables when entering directories.

Difference: direnv requires per-directory .envrc files and is language- agnostic. Envoluntary uses centralized pattern-based config and is specifically built for Nix flakes.

Attribution: All the shell integrations are adopted from direnv.

nix-direnv

Similarity: Both integrate Nix development shells with automatic directory- based loading.

Difference: nix-direnv extends direnv to work efficiently with Nix, but still requires .envrc files. Envoluntary eliminates per-directory configuration entirely through pattern matching.

Attribution: All Nix dev env caching logic is based on nix-direnv's.

flake_env

Similarity: Same similarities as nix-direnv, but flake_env is also portable.

Difference: Same differences as nix-direnv.

Attribution: Core concepts and some implementation patterns were adapted from flake_env.

envy

Similarity: Both use pattern-based matching to automatically load environments.

Difference: envy focuses on simple environment variable files, while Envoluntary leverages the full power of Nix flakes for reproducible development environments.

Attribution: The pattern-matching approach and CLI structure drew inspiration from envy's design.

Contributing

Contributions welcome! Please open an issue or pull request.

Extension points exported contracts — how you extend this code

browse all types & interfaces →

Core symbols most depended-on inside this repo

browse all functions →

Shape

Function 100
Method 36
Class 31
Enum 10
Interface 2

Languages

Rust100%

Modules by API surface

env-hooks/src/lib.rs23 symbols
nix-dev-env/src/nix_profile_cache.rs22 symbols
cli/src/config.rs18 symbols
env-hooks/src/state.rs16 symbols
cli/src/shell.rs12 symbols
env-hooks/examples/direnv/shell.rs11 symbols
cli/src/opt.rs11 symbols
nix-dev-env/src/nix_version_check.rs10 symbols
nix-dev-env/src/nix_command.rs9 symbols
env-hooks/tests/utilities.rs8 symbols
env-hooks/tests/shells.rs8 symbols
env-hooks/examples/direnv/opt.rs5 symbols

For agents

$ claude mcp add envoluntary \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page