conda-lock - Reproducible Conda Environment Locking Cheatsheet
conda-lock solves conda’s reproducibility problem. An environment.yml lists requested packages, so solving it on two machines a week apart can produce different versions — the classic “works on my machine.” conda-lock resolves the environment once and writes a lock file with exact versions, builds, and hashes for every platform you target, so installs become deterministic and fast (no solving at install time).
Installation
| Method | Command |
|---|
| pipx (recommended) | pipx install conda-lock |
| conda | conda install -c conda-forge conda-lock |
| pip | pip install conda-lock |
| Verify | conda-lock --version |
Generating a Lock File
# Lock for multiple platforms from an environment.yml
conda-lock -f environment.yml -p linux-64 -p osx-arm64 -p win-64
| Flag | Purpose |
|---|
-f, --file | Input spec (environment.yml, pyproject.toml, meta.yaml) |
-p, --platform | Target platform (repeatable) |
-k, --kind | Output kind: lock (unified), explicit, env |
--lockfile | Output path (default conda-lock.yml) |
--check-input-hash | Skip re-solving if inputs unchanged |
Lock File Kinds
| Kind | Produces | Use |
|---|
lock | Unified conda-lock.yml (all platforms) | Commit this to git |
explicit | Per-platform .lock files | conda create --file |
env | Rendered environment.yml | Tools expecting a plain env file |
# Render per-platform explicit files from the unified lock
conda-lock render -p linux-64
Installing From a Lock
# Create an environment exactly as locked
conda-lock install --name myenv conda-lock.yml
# Or with micromamba (fast)
micromamba create -n myenv -f conda-linux-64.lock
| Command | Description |
|---|
conda-lock install -n NAME | Create/update the env from a lock |
conda-lock install --mamba | Use mamba as the solver/installer |
conda create --file X.lock | Install an explicit lock directly |
Updating Dependencies
# Re-solve everything (new versions allowed)
conda-lock -f environment.yml -p linux-64 -p osx-arm64
# Update just one package, keep the rest pinned
conda-lock --update numpy -f environment.yml -p linux-64
| Task | Command |
|---|
| Full refresh | Re-run conda-lock |
| Targeted bump | --update PKG |
| Verify inputs unchanged | --check-input-hash |
Including pip Dependencies
# environment.yml
name: myproject
channels: [conda-forge]
dependencies:
- python=3.12
- numpy
- pip
- pip:
- some-pypi-only-package==1.2.3
conda-lock resolves both conda and pip dependencies into the same lock file, which is important because mixing the two ad hoc is a common source of broken environments.
CI Pattern
# Deterministic, fast CI installs
- run: conda-lock install --name ci conda-lock.yml
- run: conda run -n ci pytest
| Practice | Why |
|---|
Commit conda-lock.yml | The lock is the source of truth |
| Lock all target platforms | Devs on macOS, CI on Linux |
| Regenerate deliberately | Dependency updates become reviewable diffs |
| Cache the env | Locks make caching reliable |
conda-lock vs Alternatives
| Aspect | conda-lock | environment.yml | pixi | uv |
|---|
| Reproducible | Exact pins + hashes | No | Built-in lock | Built-in lock |
| Conda ecosystem | Yes | Yes | Yes | No (PyPI) |
| Multi-platform lock | Yes | N/A | Yes | Yes |
| Best for | Locking existing conda projects | Simple/ad-hoc envs | New conda-based projects | Pure-Python projects |
For new projects consider pixi (locking built in) or uv for pure-Python; conda-lock retrofits reproducibility onto existing conda workflows.
Resources