Hooks experimental
You can have mise automatically execute scripts during a mise activate session. You cannot use these without the mise activate shell hook installed in your shell—except the preinstall and postinstall hooks. The configuration goes into mise.toml.
CD hook
This hook is run anytimes the directory is changed.
[hooks]
cd = "echo 'I changed directories'"Enter hook
This hook is run when the project is entered. Changing directories while in the project will not trigger this hook again.
[hooks]
enter = "echo 'I entered the project'"Leave hook
This hook is run when the project is left. Changing directories while in the project will not trigger this hook.
[hooks]
leave = "echo 'I left the project'"Preinstall/postinstall hook
These hooks are run before and after tools are installed (respectively). Unlike other hooks, these hooks do not require mise activate.
[hooks]
preinstall = "echo 'I am about to install tools'"
postinstall = "echo 'I just installed tools'"The postinstall hook receives a MISE_INSTALLED_TOOLS environment variable containing a JSON array of the tools that were just installed:
[hooks]
postinstall = '''
echo "Installed: $MISE_INSTALLED_TOOLS"
# Example output: [{"name":"node","version":"20.10.0"},{"name":"python","version":"3.12.0"}]
'''Tool-level postinstall
Individual tools can define their own postinstall scripts using the postinstall option. These run immediately after each tool is installed (before other tools in the same session are installed):
[tools]
node = { version = "20", postinstall = "npm install -g pnpm" }
python = { version = "3.12", postinstall = "pip install pipx" }Tool-level postinstall scripts receive the following environment variables:
MISE_TOOL_NAME: The short name of the tool (e.g., "node", "python")MISE_TOOL_VERSION: The version that was installed (e.g., "20.10.0", "3.12.0")MISE_TOOL_INSTALL_PATH: The path where the tool was installed
Watch files hook
While using mise activate you can have mise watch files for changes and execute a script when a file changes.
[[watch_files]]
patterns = ["src/**/*.rs"]
run = "cargo fmt"This hook will have the following environment variables set:
MISE_WATCH_FILES_MODIFIED: A colon-separated list of the files that have been modified. Colons are escaped with a backslash.
Hook execution
Hooks are executed with the following environment variables set:
MISE_ORIGINAL_CWD: The directory that the user is in.MISE_PROJECT_ROOT: The root directory of the project.MISE_PREVIOUS_DIR: The directory that the user was in before the directory change (only if a directory change occurred).MISE_INSTALLED_TOOLS: A JSON array of tools that were installed (only forpostinstallhooks).
Shell hooks
Hooks can be executed in the current shell, for example if you'd like to add bash completions when entering a directory:
[hooks.enter]
shell = "bash"
script = "source completions.sh"WARNING
I feel this should be obvious but in case it's not, this isn't going to do any sort of cleanup when you leave the directory like using [env] does in mise.toml. You're literally just executing shell code when you enter the directory which mise has no way to track at all. I don't think there is a solution to this problem and it's likely the reason direnv has never implemented something similar.
I think in most situations this is probably fine, though worth keeping in mind.
Multiple hooks syntax
You can use arrays to define multiple hooks in the same file:
[hooks]
enter = [
"echo 'I entered the project'",
"echo 'I am in the project'"
]
[[hooks.cd]]
script = "echo 'I changed directories'"
[[hooks.cd]]
script = "echo 'I also directories'"