| Crates.io | envoluntary |
| lib.rs | envoluntary |
| version | 0.1.4 |
| created_at | 2025-10-25 07:20:43.303453+00 |
| updated_at | 2025-11-06 22:50:36.796147+00 |
| description | Automatic Nix development environments for your shell |
| homepage | |
| repository | https://github.com/dfrankland/envoluntary |
| max_upload_size | |
| id | 1899837 |
| size | 99,235 |
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<br/>(NixOS/home-manager)"] -->|Pro: Centralized<br/>Con: Loses project specificity| B["Management Challenge"]
C["📁 Per-Project Approach<br/>(flake.nix/direnv)"] -->|Pro: Project-specific<br/>Con: Setup burden| B
B -->|Envoluntary Solution| D["✨ Pattern-Based Centralized<br/>(Best of both worlds)"]
D --> E["✅ Centralized config<br/>✅ Project-aware<br/>✅ No per-project setup<br/>✅ Works for non-Nix projects"]
.envrc files to commit or maintainInstall:
cargo install envoluntary
Or use via Nix shell
nix shell github:dfrankland/envoluntary -c envoluntary --help
Add the shell hook to your .bashrc, .zshrc, or config.fish:
# Bash/Zsh
eval "$(envoluntary shell hook bash)" # or zsh
# Fish
envoluntary shell hook fish | source
Or use via Nix shell
# 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
Configure your environments in ~/.config/envoluntary/config.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"
Navigate to a matching directory and your environment loads automatically!
The envoluntary flake exports a Nix overlay, making it easy to integrate into
your own Nix flake.
The flake.nix in this repository is a flake-parts
module that:
envoluntary package as its defaultPackageenvoluntary available in your own flakesTo use envoluntary in your own flake.nix, follow these steps:
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
}
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
}
You can now use envoluntary in your development shell or system configuration:
devShells.default = pkgs.mkShell {
buildInputs = [ pkgs.envoluntary ];
};
The envoluntary flake exports a home-manager module for seamless integration
with your home configuration.
Note: The overlay must be applied to your
pkgsfor this module to work. See the "Using the Overlay" section above.
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
}
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";
}
];
};
};
};
The envoluntary flake also exports a NixOS module for system-wide configuration.
Note: The overlay must be applied to your
pkgsfor this module to work. See the "Using the Overlay" section above.
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
}
{
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";
}
];
};
};
}
Manually edit your config file:
envoluntary config edit
Or add entries via the CLI:
envoluntary config add-entry ".*/my-project(/.*)?" ./path/to/flake
See which entries match a given path:
envoluntary config print-matching-entries /home/user/projects/homelab
Any valid Nix flake reference works:
~/my-flakes/devshell or /home/my-user/devshellgithub:owner/repo or github:owner/repo/branchgit+https://example.com/repo.gitSee the Nix flake reference documentation for more options.
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.
Test an environment without modifying your config:
envoluntary shell export bash --flake-references ~/test-flake | source
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
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:
.envrc file in every project directorynix develop: Forces you to remember to enter shells explicitlyEach approach has drawbacks: .envrc files become noise in your repositories,
manual shells break your workflow, and scattered flakes make environment
management inconsistent.
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:
Not ideal for:
nix developEnvoluntary stands on the shoulders of giants:
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.
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.
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.
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.
Contributions welcome! Please open an issue or pull request.