# What Is mise's Approach to Shims? Dynamic Tool Resolution Explained

> Discover mise's approach to shims. Lightweight shims intercept commands and forward them to the mise binary for dynamic tool resolution without altering shell environment variables.

- Repository: [jdx/mise](https://github.com/jdx/mise)
- Tags: internals
- Published: 2026-08-09

---

**mise uses lightweight executable shims that intercept command calls and forward them to the core mise binary, enabling on-demand version resolution without modifying shell environment variables.**

mise is a polyglot tool version manager (formerly rtx) that handles runtime installations for Node.js, Python, Ruby, and hundreds of other tools. Unlike traditional version managers that manipulate PATH entries directly, **mise's approach to shims** relies on proxy executables that delegate to the core binary for runtime tool selection. This architecture allows tools to resolve to the correct version dynamically based on your current directory's [`.mise.toml`](https://github.com/jdx/mise/blob/main/.mise.toml) configuration.

## How mise Shims Work Under the Hood

When you invoke a command like `node`, mise's shim system acts as a transparent intermediary. The shim itself is a minimal executable stored in a dedicated directory that passes all arguments to `mise exec`, which then determines the correct binary to run based on your active toolset.

### Shim Generation and Storage

Shims are created automatically during tool installation. When you run `mise install node`, the core logic in `[src/shims.rs](https://github.com/jdx/mise/blob/main/src/shims.rs)` discovers every executable provided by the tool (e.g., `node`, `npm`, `npx`) and generates corresponding shim files. These files live in `~/.local/share/mise/shims` on Unix systems or `%LOCALAPPDATA%\mise\shims` on Windows.

The `[src/config/mod.rs](https://github.com/jdx/mise/blob/main/src/config/mod.rs)` file contains the `rebuild_shims_and_runtime_symlinks` function, which triggers shim recreation whenever tools are added, removed, or upgraded. This ensures the shim directory stays synchronized with your installed toolset.

### PATH Integration and Dynamic Resolution

To use shims, you add the shims directory to your PATH, typically via `mise activate --shims`. When a shim is invoked, it executes `mise exec <tool> <original-args>`, allowing mise to load the proper environment variables and select the correct version based on your current project configuration. Because the shim calls back into mise on every invocation, the actual binary can change at runtime without rewriting symlinks.

### Preventing Recursive Execution

To avoid infinite loops where a shim might call itself, mise strips its own shims from the PATH before spawning subprocesses. The `strip_shims_from_path` logic in `[src/tera.rs](https://github.com/jdx/mise/blob/main/src/tera.rs)` removes shim entries from the environment, ensuring that spawned tools reference the actual binaries rather than re-entering the shim layer.

## Practical Workflow: Installing and Using Shims

The following workflow demonstrates complete shim lifecycle management, from initial setup to maintenance:

```bash

# 1. Add shims to PATH (place in .bashrc or .zshrc for persistence)

eval "$(mise activate bash --shims)"

# 2. Install a tool - shims generate automatically

mise install node

# Creates: ~/.local/share/mise/shims/node

# Creates: ~/.local/share/mise/shims/npm

# 3. Use tools through shims - version resolves dynamically

node -v

# Actually executes: mise exec node -v

# 4. Rebuild shims after adding new executables

mise reshim

# Triggers rebuild_shims_and_runtime_symlinks to sync the directory

```

## Limitations of the Shim Approach

Shims provide command discovery but do not replicate full mise functionality. According to the `[docs/dev-tools/shims.md](https://github.com/jdx/mise/blob/main/docs/dev-tools/shims.md)` documentation, shims **do not** support shell-specific features such as `mise hook-env`, `watch_files`, or arbitrary `[env]` entries defined in [`mise.toml`](https://github.com/jdx/mise/blob/main/mise.toml). These features require `mise activate` without the `--shims` flag, which modifies the shell environment directly rather than using proxy executables.

Additionally, shims introduce a small latency overhead on each invocation because they must spawn the mise binary to resolve the correct tool version. For high-frequency scripting where microseconds matter, direct PATH activation may be preferable.

## Summary

- **mise creates shims** as lightweight wrappers in `~/.local/share/mise/shims` that forward calls to the core binary.
- **Dynamic resolution** occurs at runtime via `mise exec`, allowing version switching without symlink manipulation.
- **Recursion prevention** is handled by `strip_shims_from_path` in [`src/tera.rs`](https://github.com/jdx/mise/blob/main/src/tera.rs) before spawning subprocesses.
- **Maintenance** requires running `mise reshim` to synchronize the directory with your current toolset.
- **Trade-offs** include lack of support for shell hooks and environment variables defined in configuration files.

## Frequently Asked Questions

### How do I activate shims in my shell?

Run `mise activate --shims` and follow the output to add the shims directory to your PATH. This places `~/.local/share/mise/shims` (or the Windows equivalent) at the front of your PATH, causing the shell to find shim executables before system binaries.

### Why does mise need to rebuild shims?

Shims must be rebuilt when new executables are added or removed from your tool installations. The `mise reshim` command triggers the `rebuild_shims_and_runtime_symlinks` function in [`src/config/mod.rs`](https://github.com/jdx/mise/blob/main/src/config/mod.rs), ensuring that every binary provided by your installed tools has a corresponding shim file in the directory.

### Can shims replace `mise activate` completely?

No. While shims handle command resolution, they cannot process shell-specific features like `hook-env`, `watch_files`, or `[env]` entries from your [`mise.toml`](https://github.com/jdx/mise/blob/main/mise.toml). For full environment variable management and directory change hooks, you need standard `mise activate` without the `--shims` flag.

### How does mise prevent infinite loops when using shims?

Before executing any external command, mise calls `strip_shims_from_path` (defined in [`src/tera.rs`](https://github.com/jdx/mise/blob/main/src/tera.rs)) to remove the shims directory from the PATH environment variable. This ensures that subprocesses reference the actual tool binaries directly rather than recursively invoking mise shims.