How I use `mise` to manage my dev environment

  • 17th Apr 2025
  •  • 
  • 5 min read

Papercuts, papercuts everywhere

I work with different programming languages, and each one has its own installation method and its own toolchain.

Now thankfully, all the languages I have worked in have some form of a version manager:

These tools work fine, actually. What I get are all these tiny papercuts:

  • You spend some time learning to use one of these, and then proceed not to touch them for the next 6 - 9 months
  • They all work just different enough that you need to refer to the documentation, since this is not something you use often.
  • If you use different machines, ensuring you have all these tools installed is a bit of a chore.

This is fine

All these accumulated papercuts are starting to bother me. What I need is:

  • A single tool to rule them all
  • I should be able to use this to install a specific version of a tool I need
  • Scoping the tool to a single project/repository. That way, I do not need to manually find the right version of a tool and activate it for the project
  • It needs to work with my IDE (in my case, VSCode)

Mise to the rescue

Introducing: mise

mise sells itself as a "front-end to your dev env". The getting-started flow is simple enough:

  1. Install mise.
  2. Use mise to run node
    # Try running node
    node
    # Command 'node' not found, but can be installed with:
    # sudo apt install nodejs
    mise exec node@22 -- node -v
    # This downloads node and runs it
    # Expected output: v22.14.0
    # Try running it again:
    node
    # Command 'node' not found, but can be installed with:
    # sudo apt install nodejs

So what happened here is:

  1. I do not have node installed on my system (Ubuntu LTS running on WSL)
  2. I asked mise to run a specific version of node
  3. It downloaded it and ran it
  4. Crucially, it is not directly added to my $PATH unless I asked it to, which will be important later when you want to scope a tool's version to a specific repository.

Using it in a real project

Let's say you have a simple Nodejs project, that looks like this:

├── README.md
├── node_modules
├── package-lock.json
├── package.json
├── sql
├── src
├── tsconfig.json
└── wrangler.toml

You would do one of the following:

  • In the README, specify the node version required, and leave it up to the reader to get it themselves

OR

  • Have something like an .nvmrc that specifies which node version this project accepts, and leave it to the reader to get it themselves.

Instead, let's have mise handle this for us.

Using an LTS node version for the project

Let's say I want to use an LTS version of node for the project:

mise use node@lts

This does 2 things:

  1. It creates a mise.toml. You can commit this file to source control to ensure that other people working on your project will also get the exact same version and tool you use.
[tools]
node = "lts"
  1. mise will download and install node, if it already does not exist. It modifies your $PATH to ensure it will use the node that it has downloaded.
which node
# /home/kklee/.local/share/mise/installs/node/22.14.0/bin/node
node
# Welcome to Node.js v22.14.0.
# Type ".help" for more information.
>

Now the setup guide of the project becomes:

  1. Get mise
  2. Activate mise
  3. Clone the project
  4. mise install, this installs all the tools specified in mise.toml
  5. ????
  6. Profit

You might be thinking to yourself: "Is this any different than managing it with nvm"?

The answer is: No.

But nvm only works with node projects. If you have other languages you need to work in, mise really shines. You can now use one CLI to manage them all in a consistent fashion.

Using it with a Python project

Same as before:

mise use [email protected]

Check the python version and path before doing anything:

which python
# /home/kklee/.local/share/mise/installs/python/3.13.3/bin/python
python -V
# Python 3.13.3

Always create a virtualenv before doing anything:

python -m venv .venv/

And that is all, really.

Side Note:

I know poetry and uv exists. These are a little out of the scope of this post, maybe a topic for another day. But for now, the old school venv + pip combo is good enough for a simple demo.

Is that all mise can do?

I am barely scratching the surface of what mise can do:

  • Installing (and updating) other tools, pinned to a specific version. At $DAYJOB, the aws and AWS SAM CLI comes to mind. You can find all the tools mise can install here: registry     - This blog is written in zola and of couse, mise supports it
  • Incremental adoption. Already have a .nvmrc or .python-version in your repo? No problem, mise handles it.
  • Environment variables, secrets for local development?
  • Using it with CI?
  • Hotel? Trivago

What if I have a project/team/company that does not want to adopt mise (yet)?

So you want to use mise, but other people are not so keen about it, what to do?

The easiest way is to have a mise.toml in the project directory but not commit it.

This is, unfortunately, an error waiting to happen.

So instead, what I do is:

  1. mise recommends using a mise.local.toml file for "local config, this should not be committed to source control". https://mise.jdx.dev/configuration.html#mise-toml
  2. You can have a global .gitignore file that ignores mise.local.toml     1. Here is how you can set up a global .gitignore on your machine: https://gist.github.com/subfuzion/db7f57fff2fb6998a16c
  3. Voila! Now you can happily use mise and not have the risk of accidentally commiting a mise.toml into your PR.