Context
Modern projects depend on a plethora of tools: node, python, terraform, go, cloudflare-cli, etc. Managing these dependencies presents several challenges:
- Documentation Rot: READMEs instructing users to "install Python 3.11" inevitably go out of date or fail to specify patch versions, leading to "it works on my machine" issues.
- Inconsistent Environments: Developers and CI/CD agents need to run in the exact same environment.
- Task Sprawl: Scripts for building, testing, and deploying are often scattered across
package.json,Makefile, shell scripts, or GitHub Actions workflow files.
I need a tool that:
- Codifies the Environment: The code itself should document exactly what tools and versions are required.
- Standardizes Tasks: A single interface to run common tasks (
build,test,deploy) regardless of the underlying language or toolchain. - Simplifies CI/CD: Reduce CI configuration to "install environment -> run task".
- Manages Configuration: Uniform handling of
.envfiles and environment variables across tools.
Decision
I decided to use mise for both tool version management and task running.
Mise replaces tools like asdf, nvm, pyenv, and Make. It uses a TOML configuration file to define the exact versions of tools required and the tasks available in the project.
Consequences
Pros
- Code as Documentation: The
mise.tomlfile is the source of truth. Runningmise installguarantees the correct environment, eliminating stale setup docs. - Standardized Interface: I can swap out the implementation of a task (e.g., changing from
npm run buildtoturbo build) without changing the developer command (mise run build). - Monorepo Tasks: Supports monorepo patterns where tasks can be defined globally and overridden or composed at the directory level.
- Environment Management: Built-in
.envfile support with hierarchical overrides allows for clean separation of secrets and config. - CI/CD Simplification: Pipelines become generic. Instead of custom actions for every tool, the workflow is simply
mise install && mise run ci. - Power & Modernity: It offers features superior to
Make(better argument handling, parallel execution) andTaskfile(integrated tool management).
Cons
- Abstraction Layer: It adds an extra layer. Developers might run
mise run buildwithout knowing if it's invokingpnpm,cargo, or a shell script. - Complexity: It introduces another tool to the stack, whereas
Makeis available almost everywhere by default. - Too New: LLMs aren't familiar with it—violates LLM-Optimized. It is not broadly adopted, so coding agents regularly ignore it and try to focus on using the underlying tools it's abstracting, resulting in an inconsistent experience.