Claude Code Has an Environment Problem
Here’s a pattern I’ve hit at least a dozen times in the past month: I’m working with Claude Code on a Python project. It runs a command. Fails because the conda environment isn’t activated. Wastes 2000 tokens trying to pip install packages that already exist in my conda env. Burns through my context window debugging an environment issue that shouldn’t exist.
This isn’t Claude’s fault. The problem is conda environments - and venv, and virtualenv - all require activation state that AI tools can’t reliably track.
The pattern is always the same: you create an environment, forget to activate it, install packages globally by accident, then spend 20 minutes debugging why your script can’t find dependencies. Or worse - you’re working with AI coding tools like Claude Code that sometimes “forget” to activate your conda environment and go down re-install rabbit holes that waste time and context.
This isn’t a skill issue. It’s a tool issue.
Why UV Actually Fixes This
UV takes a radically different approach: instead of managing environments you have to remember to activate, it just runs your code in the right environment automatically.
The mental model shift is subtle but powerful. With conda or venv, you think:
- Activate environment
- Run command
- Hope you’re in the right environment
With UV, you think:
- Run command with
uv run - That’s it
No activation scripts. No sourcing bash files. No wondering if your shell is in the right state. UV figures it out from your project configuration and does the right thing.
The Exact Workflow That Changed Everything
Here’s how I actually use UV in my daily work. This is not theoretical - this is copy-paste from my terminal history.
Switch to UV for Python Development
Replace conda/venv/pip with UV for simpler dependency management
Install UV
First, install UV itself. On macOS or Linux:
| |
On Windows:
| |
That’s it. One tool, globally installed, works everywhere.
Run Your Code Directly
Instead of creating a venv, activating it, and running your script:
| |
UV automatically creates the environment, installs dependencies if needed, and runs your code. The first run takes a few seconds to set up. Every run after that is instant.
For scripts with dependencies:
| |
UV installs those packages in an isolated environment just for this execution. Perfect for one-off tasks.
Install Project Dependencies
For project-level dependencies, UV reads from your existing requirements.txt:
| |
Or install individual packages:
| |
No activation needed. UV knows which environment to use based on your current directory.
Use a Configuration File (Optional)
For more complex projects, create a pyproject.toml file:
| |
Now uv run automatically installs these dependencies before running your code. Change the dependencies in the file, run uv run, and UV handles the updates.
What This Looks Like in Practice
I recently migrated three projects from conda to UV. Here’s what changed:
Before (conda):
| |
After (UV):
| |
The cognitive overhead dropped to zero. I don’t think about environments anymore. I just run code.
Why This Matters for AI Coding Tools
Here’s the real reason I switched: UV works seamlessly with Claude Code, Cursor, and other AI assistants.
When Claude Code runs commands in your project, it doesn’t need to know about your environment setup. No special instructions about activating conda, no edge cases where it forgets the activation step, no debugging why pip installed to the wrong Python.
Just tell it to use uv run and uv pip install. The AI never needs to manage environment state, because there’s no state to manage.
I added this to my CLAUDE.md:
| |
Haven’t had a single environment issue since.
The Performance Bonus
UV is written in Rust and it’s fast. Not just “feels fast” - measurably faster than pip.
Installing pandas with pip: ~15 seconds Installing pandas with UV: ~3 seconds
For large dependency trees, the difference is even more dramatic. UV’s dependency resolver is parallel and cached aggressively. I’ve seen 2-minute pip installs complete in under 10 seconds with UV.
This isn’t the main reason to switch, but it’s a nice perk when you’re iterating on dependencies or setting up new environments.
When UV Might Not Be Right
UV isn’t perfect for every situation. Here’s when to stick with your current setup:
If you need conda-specific packages: UV uses PyPI. If you rely on conda-forge packages that aren’t on PyPI, stick with conda.
If you have complex multi-language environments: Conda shines when you need Python + R + system libraries. UV is Python-only.
If your team is locked into existing tooling: Migration cost matters. If everyone uses poetry and it works, don’t force a change.
If you need Python version management: UV doesn’t manage Python versions yet. You still need pyenv or conda for that. (Though they’re working on it.)
The Migration Path
I migrated projects one at a time over about two weeks. Here’s the safest approach:
- Install UV globally but don’t touch your existing setup
- Try
uv runon a small script to see how it feels - Create a new project with UV to get comfortable
- Pick your least critical existing project and migrate it
- Update your CLAUDE.md or AI tool config with UV instructions
- Gradually move other projects as you touch them
Don’t big-bang migrate everything. UV works alongside conda and venv just fine.
FAQ
Does UV work with existing requirements.txt files?
What about dependency locking and reproducibility?
Can I still use conda for some projects and UV for others?
How does UV know which Python version to use?
Is UV stable enough for production?
Why This Should Be the Default
Python has a packaging problem that’s existed for 15 years. We’ve tried to fix it with pip, virtualenv, conda, poetry, pipenv, and a dozen other tools. Each one solves part of the problem while creating new complexity.
UV is the first tool I’ve used that actually feels simpler than the problem it solves. Not simpler in a “we abstracted the complexity” way - simpler in a “we eliminated the complexity” way.
The fact that it works seamlessly with AI coding tools is just validation that the design is right. If a tool is simple enough that an AI can use it without special-casing environment state, it’s simple enough for humans too.
Conclusion
Key Takeaways
- UV replaces pip, venv, and virtualenv with a single fast tool that requires no environment activation
- Run code with uv run and install packages with uv pip install without thinking about environment state
- UV works seamlessly with AI coding tools like Claude Code because there is no activation state to manage
- Installing dependencies is 3-5x faster than pip thanks to UV’s Rust implementation and parallel resolver
- UV reads standard requirements.txt files so migration from existing projects is straightforward
- Add UV commands to your CLAUDE.md to prevent AI tools from environment activation issues
- Stick with conda if you need conda-forge packages or multi-language environments
I spent years managing Python environments, trying every tool, reading every blog post about best practices. UV is the first tool that made me stop thinking about environments entirely. That’s the real test of good tooling - when it disappears from your mental model and just works.
Try it on one project. If it doesn’t click, you’ve lost 10 minutes. If it does, you’ll wonder why you didn’t switch sooner.