mise-en-place welcomes 2025 #4057
jdx
announced in
Announcements
Replies: 2 comments
-
I use mise everyday and it's so good that I could almost forget it's there in the first place. The only downside for me is that it's particularly frustrating to pair-program on a coworker's computer when they don't have it installed ! Thank you for this great tool :) |
Beta Was this translation helpful? Give feedback.
0 replies
-
Mise is such a great tool! 🥳 We've started using it in the team and have found it very useful! You mention some planned improvements to tasks. Perhaps you know of them, but if not take a look at Taskfile. Might provide some some inspiration for mise tasks (it's very mature). |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
2024 was a big year for mise. Approximately 1 year ago mise was renamed from rtx and the scope was expanded from being a simple polyglot version manager to being "the front-end to your development environment" with tasks and env var management. Countless bugs have been squashed and features added. Given it's been about a year since the last time I had a similar post I wanted to cover what we've accomplished.
This post is relatively advanced, and I'm expecting a pretty decent knowledge of mise and how it works—at least in some sections. The audience I'm thinking about is someone who's been using mise for at least a few months that doesn't read release notes very often and wants to know what new things are available.
Tasks
After much testing, experimentation, and feedback, mise tasks are now out of experimental. mise tasks are a way to define scripts for projects and give other developers an easy way to run them. It's an alternative to the way projects commonly use Makefiles, shell scripts, or other tools like just and Taskfile.
The obvious benefit to integrating a tool manager and a task runner is that mise can setup the tools needed to run tasks before the task is executed. Tasks can define a different set of tools per task. Don't assume that's the only benefit though, mise tasks are very capable—you'll be unlikely to find a feature missing in mise tasks that similar tools provide.
mise run
shorthandInstead of running a task like
mise run build
, mise supports shorthand withmise build
.Caution
If mise introduces a new command that conflicts with your task, the task will need to use
mise run conflicting-name
. For this reason, don't use the shorthand syntax in documentation or scripts because new mise versions may cause the task to no longer work. It's great for running in the terminal though.mise run
selector UIYou can also run
mise run
(with no args) which will show a selector UI to pick a task to run:A similar selector UI was added to
mise use
with no args.Task Args and Completions
Early on when designing tasks I had a challenging use-case in mind that I wanted to support. I wanted users to be able to write tasks that not only could support argument/flag parsing as advanced as mise itself, but also users to be able to write custom completion code easily.
This is certainly without question the feature I'm most proud of in mise right now. Dynamic completions is a problem I've been thinking about for a long time. I'm not aware of any dev tools out there that are able to support this level of dynamic completions.
A lot of moving parts had to come together to make this work, mostly in my other project usage, but it's in now so you can define a task like this which has custom "username" completions:
Having arg/flag value completions like this can be a huge boon to users of tasks that you author. Definitely take the time to see if you can add these to your tasks (it's not hard) and make sure you document that these completions will happen.
Note
If you have a CLI that needs advanced completion functionality like this definitely take a look at usage. usage was designed with CLI vendors in mind to help them build complex completion logic without needing to actually write completion scripts for each shell individually. If you've never written completion code, trust me when I say it certainly is neither fun nor easy. usage would benefit from other CLIs adopting it and giving feedback since today it pretty much is only used for mise, but that's not how I want usage to be long-term.
New Backends
The following are the backends added in 2024:
Important
A common misunderstanding is users thinking mise just "wraps" tools like asdf or aqua. In general that is not the case and mise instead re-implements most of these tools. mise does not use asdf, the aqua CLI or the vfox CLI. It's compatible with their plugins because it has full re-implementations in rust. That said, for package manager backends like dotnet, npm, pipx, etc—mise does wrap those tools. The upside of reimplementing is that mise has a lot more control over the behavior, it's faster, and doesn't require you to have anything preinstalled. The downside is it increases the maintenance burden.
New Core Tools
Here's the new core tools added in 2024:
added for macos, linux should be coming soon
Note
If you'd like to see a new core tool, please let me know before you work on it. It's a large maintenance commitment for me to add new core tools and I likely will not be willing to accept it.
Secrets
sops integration was added to
env._.file
directives for storing secrets in a project repo. This allows you to take a file containing secret env vars like the following:An age key needs to be created, then with sops this can be encrypted with
sops encrypt -i --age "<age_public_key>" .env.json
which can then be imported with mise:Redactions
To prevent displaying sensitive env vars or secrets (specifically when running tasks, but this logic is used throughout mise), mise can redact its output. To configure, give the name of a key to redact or set
redact = true
when importing a secret file:Hooks
Hooks are now available which allow you to do things like execute a command when entering a directory or when tools are installed. See docs for more. This even can allow you to do things like add completions when entering a directory, something direnv can't even do.
Docs improvements
When we started 2024 the mise docs consisted of a single, huge README. Now we have a detailed website with loads of information to learn about how to use mise effectively.
Have a look at the following new portions of the docs:
Special thanks to @hverlin who's done a bunch of work improving the docs.
Windows/Powershell Support
Special thanks to @fgilcc for getting Powershell support.
Fragmented
conf.d
config filesSometimes you want to break up mise.toml files into multiple separate files. mise will now read files such as
.config/mise/conf.d/*.toml
so you can have as many files in there as you like. See Configuration for more on what files mise looks for.Supply Chain Security
The supply chain work completed in mise has been substantial. I wrote another post covering that work:#4054.
Tool aliases
Aliases went through an overhaul. Previously "aliases"
was a feature that allowed you to have aliases for tool versions but now aliases can be used for backends as well. This is useful if you want to override the default backend for a tool for some reason:
Of course aliasing versions is still supported as well:
Which can be used with
mise use node@my_custom_node
.Postinstall on tools
If you want to run some code after a tool is installed, a new generic "postinstall" hook can be added to
mise.toml
:Python venv improvements
Automatically activating venvs when entering a project directory is certainly a favorite for mise users. Unfortunately it also has been a challenge to make it work well in various setups. Significant work has been done here that is largely invisible but mise should behave more predictably and has extension points like
MISE_PYTHON_VENV_CREATE_ARGS
.mise-poetry has also had quite a few improvements made to its venv activation.
Special thanks to @syhol who has spent a lot of time figuring out the right behavior mise should have and identifying issues with venvs over the last few months.
uv
Integrationuv
has taken the Python ecosystem by storm and we're very strong advocates for it. To that end, we've added some places to make it easier to use mise and uv together.MISE_PYTHON_UV_VENV_AUTO
this essentially just automatically creates/activates a uv venv when entering a directory withuv.lock
in it. If I wrote Python—this is probably how I would use it with mise since it doesn't require adding configuration tomise.toml
for every uv project you work with.mise sync python --uv
is a new 2-way sync command to merge uv pythons with mise pythons. This symlinks python installs from either tool to the other so you don't need to install multiple copies of the same python on your system.Expect to see continued progress here as
uv
adds functionality and we identify places it can integrate better.Python precompiled binaries from Astral
The precompiled pythons we use in mise have been receiving a lot of love from Astral which took that project over. Because uv also uses these same pythons, it's important for them that they work well.
While we default to using these binaries, we also show a hint the first time they're used informing the user that they may not work as well as compiled pythons. While it is unfortunately still the case that precompiled binaries are not 100% reliable with Python, they have improved significantly over the last few months and are continuing to improve thanks to Astral's work. If they didn't work for you a few months ago, I would certainly give it a try again since many issues have been resolved.
I wasn't sure if we should default to precompiled or not and sent out a poll on GitHub. At that time, Python users voted unanimously for defaulting to precompiled so that's what we did. Even though these do cause some problems, I think the consensus has been it's a worthwhile change mostly just because it makes installing python like 20x faster—and they come with more optimizations so the pythons actually run faster than python-build pythons using the default options.
As I understand it, some of the work involves upstream changes to cpython but in my lurking I noticed that cpython is accepting patches for this stuff—who knows, maybe cpython will release these precompiled binaries on python.org one day like node has. One can certainly dream!
Kudos to @charliermarsh, @indygreg, and the astral team since this is a big help for python development for both uv and mise.
mise en <DIR>
mise en
is a new command that lets you drop into a directory with the mise tools configured, it's a lightweight alternative tomise activate
if you don't want to use shell hooks. As you may know, I hate shell hooks, even mise's.If I'm honest though, I mostly just wanted this because I think it's funny. I don't think too many people will use it since
mise exec|run
andmise activate
cover most of what users need. Still, it's worth remembering this is here in case you want something between those 2 options.mise upgrade --bump
mise up|upgrade --bump
is actually a pretty complex flag. What it does is upgrade to the latest version of a tool and updatesmise.toml
to the new version with the same semver specificity. This is easier to see with an example, assume we started here:But
[email protected]
and[email protected]
are the latest versions. Normally if you usedmise up
it would respect the current fuzzy-version specified—so it'd give you the latest node@20 and [email protected], it wouldn't upgrade past that.Of course, users expected that it should do that, but it was a tricky thing to build! Thankfully we have it now so if you instead run
mise up --bump
it'll upgrade the tools to the latest available version and updatemise.toml
to look like this:mise generate
commandsA bunch of new commands have been added that essentially create files for various reasons.
mise generate git-pre-commit
Creates a
.git/hooks/pre-commit
hook to execute a mise task when committing to the repo. This is my personal favorite one, I use it in all of my projects now and find it so much nicer to just use mise (which I'm already using) than setting up tools like lefthook or husky for this task.Those tools offer more functionality in the hook, but frankly I've found I just don't really need it. Often just running
cargo fmt
orprettier -c .
is all I really want to do in a pre-commit hook anyhow.mise generate github-action
Creates a stock
.github/workflows/test.yml
workflow usingjdx/mise-action
. This is a great scaffolding step when setting up a new project so you don't need to remember all the syntax and yak shaving necessary to set up a GitHub Action.mise generate config
By default, this just creates a
mise.toml
file with a bunch of helpful comments explaining different configuration options, however if you're migrating from asdf check out the--tool-versions
flag which can be used to create amise.toml
file out of a.tool-versions
file.mise generate task-docs
Creates a markdown file of all the project's tasks with descriptions. Useful for showing contributors
what tasks are available.
I think more could be done with this command, the output is fairly spartan at the moment, but it has the basics.
mise generate bootstrap
The use-case here is primarily working on a project with other people that may not want to install mise globally. This will create a shell script to idempotently (and securely via checksums) fetch the mise binary and run mise, by default with a
bin/mise
script.You can also set the
--localize
flag in order to additionally put all of the mise installs, cache, state, and other internal files into a hidden.mise
directory so all of mise is sandboxed. This can be helpful if you want to use a specific version of misejust for a single project. That said, I'm quite careful when it comes to breaking changes in mise and from 2025 onwards I expect breaking changes to be exceedingly rare. You should feel comfortable using the latest version of mise for all of your projects without worrying about breaking changes.
mise generate task-stubs
This creates stubs like
bin/build
orbin/clean
for each task in a project. This is often paired withmise generate bootstrap
to give other users on a project simple shims they can execute to run tasks without "installing" mise.Editing commands
New commands have been added that edit
mise.toml
files so you don't need to edit them manually.mise config set key value
This is the generic toml-editing command which can be used to edit any part of a
mise.toml
config file:$ mise config set tools.node.postinstall "npm install -g neovim"
mise settings KEY=value
I love this command and use it all the time—you'll find it all over the docs too since it's a great way to permanently edit settings in mise. As an example, if you want to see status information as mise loads/unloads config files:
mise settings
mise set KEY=value
Easy way to set env vars in mise:
mise set NODE_ENV=staging
mise task add <TASK>
Create a new task (file (with
--file
) or toml task):Special thanks to @roele who has been improving these commands quite a bit. He has also done a lot of work in demand which is the library mise uses to display prompts and its TUI features.
Settings Codegen
This is an internal change, but it's worth knowing about in case you ever contribute to mise. mise has loads of settings to customize its behavior. These can be set either in a config file or with env vars. Previously, these were defined in many places and keeping all of the code in sync was a real hassle. Today, the settings are defined in a single toml file.
The code, docs, json schema, and a bunch of other stuff all gets generated from the definitions in this one file. If you're ever looking to contribute to mise, this is where you want to look if you need to add/edit a setting.
For users, this basically just means that the settings docs don't go out of sync anymore which was a common issue before.
mise.lock
lockfilemise.lock
is an experimental feature that allows you to pin tool versions in a file separate frommise.toml
. I assume you're familiar with this concept since pretty much all modern package managers have something similar likepackage-lock.json
for npm oruv.lock
for uv.One feature users coming from asdf love about mise is that they have the choice of using fuzzy-versions in
mise.toml
for tools likenode = "20"
instead of needing to define exact versions. mise has always had the--pin
flag on commands likemise use
to help make pinning easier, but with a separate lockfile now you can keep fuzzy versions inmise.toml
and still ensure developers/CI use the same pinned version through the use ofmise.lock
. Renovate has support formise.lock
so you can have your tools automatically updated in PRs. Otherwise you can update to the latest matching version withmise upgrade
or simply by deleting the lockfile and creating it again.Lockfiles are a bit on the rare side of cooked. It needs to go through significantly more testing before it comes out of experimental. Right now, you need to enable experimental, then you create an empty
mise.lock
withtouch mise.lock
next tomise.toml
and mise will fill it in for you when it installs things. I would not be surprised if this behavior changes before it comes out of experimental though.Once lockfiles are fully complete, I think everyone currently using
--pin
should likely switch over to lockfiles somise upgrade
works.mise upgrade
updates tools to the latest matching fuzzy-version, and if you pin that obviously means a tool can't be updated.mise fmt
mise fmt
is a simple command that reindents yourmise.toml
, reorders the keys, and makes other whitespace/formatting changes to the config to make them consistent. This is relatively basic right now but I plan to continue adding to it over time.mise install-into
mise install-into
is a new command that installs a tool into a specific directory outside of mise's install directory. This is useful if you want to use mise to grab a tool but don't want to actually manage it with mise. One example of this would be setting up a Dockerfile where you just want to add some tools but don't want to use mise at runtime—likely just because you want to keep your docker image simple and don't need to dynamically switch versions once the container is built.mise tool
mise tool
this is similar tomise ls
but shows output of a single tool instead of multiple—allowing me to display more information than I could in a table. Right now this is helpful if you want to know what backend a tool is using, but I am sure this will be extended further over time for other information about a specific tool in mise.mise watch
mise watch
is mostly a wrapper for watchexec on top ofmise run
. The syntax was simplified for this so now instead of needing to runmise watch -t mytask
you just need to runmise watch mytask
. Watchexec arguments tomise watch
have always been accepted, likemise watch mytask --clear
to clear the screen on each run but in new versions the help output formise watch
lists all the available watchexec flags where before it didn't.env directives
Directives like
env._.path
andenv._.file
have gone through many improvements over the last year.One that I like is that
env._.source
can now edit PATH where before it was not able to do that—well, it can add items to the start of PATH right now but nothing else. That's probably what 99% of people do with PATH though.env._.file
now accepts json and yaml instead of .env syntax. In fact, I certainlyrecommend json or yaml over .env since dotenv syntax is not really a standard so different tools will interpret .env files differently.
Lazy eval env vars
Some env vars need to be loaded before tools are set up when mise initializes but sometimes after.
For example, you may need to set
LD_LIBRARY_PATH
in order to install some tool, but for a different env var you may want to exec some code that uses a mise tool. Previously, all env vars were resolved before tools so the latter use-case wasn't possible. Now, atools = true
property can be added to all env vars and env directives which will cause mise to instead resolve it after tools are loaded.mise activate
hook on CDThe internals of how
mise activate
callshook-env
have changed slightly. Now in bash, zsh, and fish,hook-env
will be executed anytime the prompt is displayed (as before), but also when changing directories.This means you can do stuff like this now:
(assume ~/src/myproj/mise.toml has some node version set which is different from the global version)
Because before
hook-env
only was executed when the prompt was displayed—and the prompt wouldn't be displayed between these commands—this did not previously work the way you'd expect. You'd just have the global version of node both times.mise activate
automatically removes shims directoryThis was a minor change but worth calling out. If you have the shims dir in PATH and later call
mise activate
, mise will now remove the shims directory. Having the shims directory and activating used to be a somewhat problematic situation so the guidance was to avoid it, but we realized that by allowing users to do this means they can do things like add shims to PATH for non-interactive setups and later call activate in zshrc (or equivalent) which makes setup a bit easier since not so many conditionals are needed.Pitchfork
Pitchfork is a project separate to mise, but it's definitely worth calling out since it fills a gap in mise and very well could have just been a mise feature.
Pitchfork is a daemon manager whose killer feature is integrating with your shell session. Pitchfork is able to autostart/autostop daemons when entering/exiting projects. So for example if you have a redis daemon you want to start when inside
~/src/myproj
, pitchfork can be configured to automatically start redis when the first shell session enters that directory and kill redis after the last one leaves. Of course if multiple shell sessions enter~/src/myproj
pitchfork will only start the 1 session.I've always been frustrating running things like app/doc servers in separate terminal tabs which I inevitably forget to close—then they use up a port that I might need later when running other things. Pitchfork solves that for me because it only runs daemons while I'm actively working on a particular project.
It's not clear yet exactly how this would work but I want to improve hosting a bit more, possibly making it work similar to something like typicode/hotel that could run daemons listening on routes like
http://redis.localhost
which is much friendlier than a port number. For now though, it just runs daemons and port mappings/conflicts are up to you to handle.If you've been looking for a way to run background tasks with mise, this is likely what you're looking for.
Pitchfork is young, and I've only spent a few days working on it—though the basic feature set works well enough for me
to use personally. Expect issues for now but it's also not that complex of a tool. The main issue is right now it takes a back seat to mise development. Once I get around to looking at it again I don't think it will take much more to harden into a solid tool.
Registry
mise originally had a list of all the tools as a fork of the asdf-vm/asdf-plugins repo. That obviously meant the only backend could be asdf so when I introduced alternative backends that contained default tools like vfox, aqua, and ubi—we needed a different source. Now this is called the registry and it's a single toml file in the root of mise's codebase.
If you ever want to make a contribution to the registry—such as if you notice a tool is supported by aqua and tested to make sure it works—you'll want to make a PR to that file. A GitHub Action will do a bunch of automation on your PR and make a commit to it containing some generated code, so be prepared to see that happen. registry.toml is the only file you should need.
That said, the syntax in this file is beginning to get fairly complex as the registry has gained features. It's possible this file get broken out into separate files per tool at some point if it grows beyond a few thousand lines.
IDE Extensions
@hverlin has gone to town on his vscode extension and is continuing to make improvements to it. I highly recommend it for anyone using vscode with mise.
I know there are other IDE extensions as well—though I haven't had a chance to try them myself.
Future of mise
In general, expect far fewer features in 2025 than we had in 2024. I had a scope in mind for a "complete" mise at the beginning of 2024 which included tasks and env var management and we've hit that goal for sure. Today though, mise is
quite big, the docs are large and there is a lot to learn for people new to mise. It's possible I may change my mind about this, but I don't intend to put any more major features into mise. If I have new ideas they'll likely be tools that integrate with mise like pitchfork.
I have updated the roadmap for 2025 so look there if you want to see specifics on what is likely to improve in mise over the next year. It's pretty much just small improvements to mise's existing feature set.
You should certainly see this as good news. mise has hit a mature stage and now it's a matter of refining what is there and much less experimentation on what mise should become.
How you can help
Here's some suggestions on ways you can help make mise better:
GitHub Stars
The stargazer count continues to grow. We hit 10k last year. mise is also one of the top 100 tools on homebrew.
Some other notable events:
Thanks
Lastly, thank you all for helping build mise over the last couple of years. Without people using mise there'd be no reason to do it of course but more than that you've collectively spent countless hours putting mise through its paces and working with me to improve it.
Of course there's also been some stellar code people have contributed along the way too which is great to see—I especially love it when people tell me they've never written rust before but are willing to dive into an admittedly daunting language to help improve mise. It's awesome to see.
I think I'll try to keep this as a regular annual thing. I like the model I've settled in of having frequent small updates to the CLI which effectively allows me to "soft-launch" features, get them baked in a bit and have a larger annual announcement—or some sort of cadence.
Beta Was this translation helpful? Give feedback.
All reactions