Skip to content

Coming from direnv, devenv and mise

This page maps what you know from direnv, devenv and mise onto reprobuild, explains where they differ, and says when those tools remain the better choice.

What carries over

  • The environment follows the directory. Entering a project switches its environment on; leaving switches it off.
  • A directory has to be allowed first. direnv allow and repro allow both stop a newly cloned repository from changing your shell before you have looked at it.
  • Tool versions belong to the project. A .mise.toml or a devenv.nix names the tools a project needs; so do the uses: lines of a repro.nim.
  • Tasks and processes belong to the project too, as mise tasks and devenv scripts and processes do.

Concept map

direnv, devenv or misereprobuild
.envrc, devenv.nix, .mise.tomlthe devEnv: block of the project file
eval "$(direnv hook bash)"eval "$(repro shell hook bash)"
direnv allow, direnv denyrepro allow, repro deny
direnv exec DIR COMMANDrepro exec -- COMMAND
use flakeuseFlakeDevShell()
tool versions in .mise.tomluses: version ranges, resolved into `repro.lock`
mise tasks, devenv scriptstasks: repro tasks, repro run
devenv processes and servicesservices: repro up, repro down

Before and after

An .envrc that loads a flake's dev shell:

use flake

becomes a repro.nim that does the same, with no direnv involved:

import repro_project_dsl
import repro_dsl_stdlib/foreign_env

package projectEnvironment:
  devEnv:
    useFlakeDevShell()

While teammates move over, repro hooks ensure --shell-direnv writes an .envrc that hands activation to reprobuild, so people who still use direnv get the same environment from the same repro.nim.

What works differently

The environment is declared, not scripted. An .envrc is a shell script and can run anything. A devEnv: block declares tools, variables, tasks and services, and the compiler checks it. Where you need logic, you write it as typed Nim in the project file.

The build uses the same environment. The tools your shell gets are the tools the build resolves, from the same project file and the same lock file. There is no second description of the toolchain to keep in step.

Trust follows the directory, not its contents. repro allow records trust against the directory's path. After that, a change to repro.nim, such as one that arrives with git pull, is activated the next time you enter the directory without asking again. Allow only directories whose changes you would run yourself.

What reprobuild does not do

  • It does not run arbitrary shell code when it activates an environment.
  • It does not ask for trust again when a project file changes.
  • It does not switch tool versions for directories that have no project file.

When the other tool remains the better choice

  • direnv, when you want per-directory variables with shell logic, in repositories that reprobuild does not build.
  • mise or asdf, when you only switch tool versions across many unrelated repositories and have no use for a build tool.
  • devenv, when your team has standardised on Nix modules for services and wants those modules, not reprobuild's services.

Next steps