docs/dev-tools/mise-lock.md
mise.lock is a lockfile that pins exact versions and checksums of tools for reproducible environments. Lockfiles are not created automatically—you must run mise lock to generate them. Once a lockfile exists, mise will keep it updated as tools are installed or upgraded.
The lockfile serves similar purposes to package-lock.json in npm or Cargo.lock in Rust:
mise.tomlGITHUB_TOKEN in most casesLockfiles are controlled by the lockfile setting:
# Enable lockfiles globally
mise settings lockfile=true
# Or set in mise.toml
[settings]
lockfile = true
mise.lock file exists, running mise install or mise use updates it with the exact versions installedmise.lock exists, mise will prefer locked versions over version ranges in mise.tomlmise.lock is a TOML file with a platform-based format that organizes asset information by platform:
# Example mise.lock
[[tools.node]]
version = "20.11.0"
backend = "core:node"
[tools.node.platforms.linux-x64]
checksum = "sha256:a6c213b7a2c3b8b9c0aaf8d7f5b3a5c8d4e2f4a5b6c7d8e9f0a1b2c3d4e5f6a7"
size = 23456789
url = "https://nodejs.org/dist/v20.11.0/node-v20.11.0-linux-x64.tar.xz"
[[tools.python]]
version = "3.11.7"
backend = "core:python"
[tools.python.platforms.linux-x64]
checksum = "sha256:def456..."
size = 12345678
# Tool with backend-specific options
[[tools.ripgrep]]
version = "14.1.1"
backend = "aqua:BurntSushi/ripgrep"
options = { exe = "rg" }
[tools.ripgrep.platforms.linux-x64]
checksum = "sha256:4cf9f2741e6c465ffdb7c26f38056a59e2a2544b51f7cc128ef28337eeae4d8e"
size = 1234567
Each platform in a tool's [tools.name.platforms] section uses a key format like "os-arch" (e.g., "linux-x64", "macos-arm64") and can contain:
checksum (optional): SHA256 or Blake3 hash for integrity verificationsize (optional): File size in bytes for download validationurl (optional): Original download URL for reference or re-downloadingEach tool entry ([[tools.name]]) can contain:
version (required): The exact version of the toolbackend (optional): The backend used to install the tool (e.g., core:node, aqua:BurntSushi/ripgrep)options (optional): Backend-specific options that identify the artifact (e.g., {exe = "rg", matching = "musl"})platforms (optional): Platform-specific metadata (checksums, URLs, sizes)The platform key format is generally os-arch but can be customized by backends:
linux-x64, macos-arm64, windows-x64ubi may include additional tool-specific information in the platform keyWhen using environment-specific configuration files (e.g., mise.test.toml), each environment gets its own lockfile:
| Config file | Lockfile |
|---|---|
mise.toml | mise.lock |
mise.test.toml | mise.test.lock |
mise.staging.toml | mise.staging.lock |
mise.local.toml | mise.local.lock |
mise.test.local.toml | mise.test.local.lock |
For example, with MISE_ENV=test:
MISE_ENV=test mise lock # creates mise.lock AND mise.test.lock
Tools from mise.toml go to mise.lock, tools from mise.test.toml go to mise.test.lock.
Resolution: When MISE_ENV=test, mise reads mise.test.lock for tools defined in mise.test.toml and mise.lock for tools in mise.toml. Environment-specific lockfiles are strictly scoped to their corresponding config — they only contain tools defined in that config.
This design means CI environments that don't set MISE_ENV only depend on mise.lock, so dev tool version bumps in mise.dev.lock won't invalidate CI caches.
Both mise.lock and mise.<env>.lock files should be committed to version control. mise.local.lock and mise.<env>.local.lock should be gitignored alongside their corresponding config files.
Tools defined in mise.local.toml (which is typically gitignored) use a separate mise.local.lock file. This keeps local tool configurations separate from the committed lockfile.
# mise.local.toml tools go to mise.local.lock
mise use --path mise.local.toml node@22
# Regular mise.toml tools go to mise.lock
mise use --path mise.toml node@20
Use mise lock --local to update the local lockfile for all platforms:
mise lock --local # update mise.local.lock
mise lock --local node python # update specific tools in mise.local.lock
The locked setting enforces that all tools have pre-resolved URLs in the lockfile before installation. This prevents API calls to GitHub, aqua registry, etc., ensuring fully reproducible installations.
# Enable strict mode
mise settings locked=true
# Or via environment variable
MISE_LOCKED=1 mise install
When enabled, mise install will fail if a tool doesn't have a URL for the current platform in the lockfile. To fix this, first populate the lockfile with URLs:
mise lock # generate URLs for all platforms
mise lock --platform linux-x64,macos-arm64 # or specific platforms
This is useful for CI environments where you want to guarantee reproducible builds without any external API dependencies.
# Generate the lockfile
mise lock
# Install tools using locked versions
mise install
# Install exact versions from lockfile
mise install
# Update tools and lockfile
mise upgrade
When you want to update tool versions:
# Update tool version in mise.toml
mise use node@24
# This will update both the installation and mise.lock
Backend support for lockfile features varies:
aqua, http, github, gitlab
aqua, github, core:python (precompiled binaries), core:ruby (precompiled binaries), core:zig (install-time)vfox (tool plugins only)ubicore (some tools)asdf, npm, cargo, pipx# Always commit the lockfile
git add mise.lock
git commit -m "Update tool versions"
mise.toml with new version rangesmise install to update mise.lockmise install to get exact versions# Example GitHub Actions
- name: Install tools
run: |
mise install # Uses exact versions from mise.lock
- name: Cache lockfile
uses: actions/cache@v5
with:
key: mise-lock-${{ hashFiles('mise.lock') }}
If checksums become invalid or you need to regenerate them:
# Remove all tools and reinstall
mise uninstall --all
mise install
When merging branches with different lockfiles:
mise.lockmise install to verify everything works# In project's mise.toml
[settings]
lockfile = false
# Convert .tool-versions to mise.toml
mise config generate
# Enable lockfiles and generate the lockfile
mise settings lockfile=true
mise lock
mise install
# Set versions based on package.json
mise use node@$(jq -r '.engines.node' package.json)
In addition to lockfiles, mise supports the install_before setting to limit supply chain risk by only installing versions that have been available for a minimum amount of time:
[settings]
install_before = "7d" # only resolve to versions released more than 7 days ago
This pairs well with lockfiles — use install_before to avoid picking up brand-new releases, and lockfiles to pin the exact versions you've vetted.