Skip to content

What Is the Best Workflow for Setting Up Python Virtual Environments in VS Code?

Problem

I opened VS Code and started a new Python project. I ran the usual commands:

terminal
python -m venv .venv
source .venv/bin/activate
pip install requests pandas

Then I opened a new terminal in VS Code to run my tests. They failed immediately.

terminal
$ python test.py
Traceback (most recent call last):
File "test.py", line 1, in <module>
import requests
ModuleNotFoundError: No module named 'requests'

The virtual environment wasn’t active in the new terminal. I forgot to run source .venv/bin/activate again.

This happens constantly. Every new terminal tab requires activation. Every time I forget, packages install globally. Every time I switch projects, I need to find and activate the right venv.

A Reddit thread confirmed I’m not alone. Developers shared their frustrations with the repetitive venv setup workflow. The top comment with 15 upvotes was blunt: “Don’t waste time managing virtual environments. Learn how to use uv. It takes care of everything for you.”

Why This Matters

Python virtual environment friction costs real time:

Time Wasted Per Project
1. Create venv: 5 seconds
2. Activate in terminal: 5 seconds
3. Activate again in new terminal: 5 seconds
4. Debug why packages aren't found: 10 minutes
5. Fix accidentally installed global packages: 15 minutes
6. Configure .gitignore correctly: 5 minutes
7. Set up VS Code interpreter: 2 minutes
Total per project: 30+ minutes of friction

Multiply that across 20 projects per year, and I’m losing 10+ hours annually just on environment setup.

The Traditional Workflow (What I Used to Do)

Let me trace through the painful traditional approach:

Step 1: Create Virtual Environment

terminal
# Navigate to project
cd ~/projects/my-python-app
# Create venv with standard naming
python -m venv .venv

Step 2: Activate (Different Commands Per OS)

activation.sh
# macOS / Linux
source .venv/bin/activate
# Windows Command Prompt
.venv\Scripts\activate.bat
# Windows PowerShell
.venv\Scripts\Activate.ps1

I constantly forgot which command to use when switching between my Mac and Windows machines.

Step 3: Configure .gitignore

terminal
# Don't forget this step!
echo ".venv/" >> .gitignore

If I forgot, my repository would bloat with 500+ megabytes of venv files.

Step 4: Configure VS Code

In VS Code, I had to manually select the interpreter:

VS Code Steps
1. Cmd+Shift+P (Mac) or Ctrl+Shift+P (Windows)
2. Type: "Python: Select Interpreter"
3. Find and select: ./venv/bin/python

Then I had to enable auto-activation in settings:

.vscode/settings.json
{
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
"python.terminal.activateEnvironment": true
}

Step 5: Repeat For Every New Terminal

Every time I opened a new terminal in VS Code, I needed to verify activation:

terminal
# Check if venv is active
$ which python
/Users/me/projects/my-app/.venv/bin/python # Good - venv is active
# If you see this instead:
/Users/usr/local/bin/python # Bad - system Python, not venv!

The Better Workflow: Git-Integrated Setup

After reading the Reddit thread, I improved my workflow with a one-time global configuration:

One-Time Global Setup

terminal
# Create global gitignore for venv
echo ".venv/" >> ~/.gitignore_global
# Configure git to use it
git config --global core.excludesfile ~/.gitignore_global

Now I never forget to exclude .venv/ from any project.

Per-Project Setup

terminal
# Create venv - Python 3.11+ adds .gitignore automatically!
python -m venv .venv
# Verify auto-generated .gitignore exists
cat .venv/.gitignore
# Output: *

Python 3.11+ automatically creates a .gitignore inside the .venv directory. This means git ignores everything in the venv folder by default.

VS Code Auto-Detection

VS Code’s Python extension automatically detects .venv directories:

VS Code Behavior
1. Open folder containing .venv
2. VS Code shows notification: "We noticed a virtual environment in this folder"
3. Click "Yes" to select it as the interpreter
4. Terminal auto-activates the venv

This reduced my setup from 5 manual steps to just creating the venv.

The Modern Workflow: Using uv

The Reddit thread’s top-voted response convinced me to try uv. Here’s what changed:

Install uv Once

terminal
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Create and Run Projects

terminal
# Create new project - venv handled automatically
uv init my-project
cd my-project
# Add dependencies - no activation needed!
uv add requests pandas pytest
# Run scripts - uv handles everything
uv run python main.py
uv run pytest

No manual python -m venv. No source .venv/bin/activate. No VS Code interpreter selection. uv handles everything.

Comparison Table

Workflow Comparison
| Step | Traditional | Git-Integrated | uv |
|-------------------|-------------|----------------|------------|
| Create venv | Manual | Manual | Automatic |
| Activate venv | Every term | Auto (VS Code) | Not needed |
| Install packages | pip install | pip install | uv add |
| Run scripts | python x.py | python x.py | uv run |
| .gitignore setup | Manual | Semi-auto | Automatic |
| Lock file | Manual | Manual | Automatic |
| Time per project | 30+ min | 5 min | 1 min |

Common Mistakes I Made (And Fixed)

Mistake 1: Naming venv Something Other Than .venv

terminal
# WRONG - VS Code won't auto-detect
$ python -m venv my-cool-env
$ python -m venv venv
$ python -m venv env
# CORRECT - VS Code auto-detects .venv
$ python -m venv .venv

VS Code specifically looks for .venv by default. Other names require manual interpreter selection.

Mistake 2: Committing the .venv Folder

I once committed a 300 MB venv to a git repository. My teammates were not happy.

terminal
# If you already committed .venv, fix it:
git rm -r --cached .venv
echo ".venv/" >> .gitignore
git commit -m "Remove venv from version control"

Mistake 3: Creating venv Outside Project Directory

terminal
# WRONG - Harder to manage
$ cd ~/venvs
$ python -m venv my-project-env
$ cd ~/projects/my-project
# CORRECT - Keep venv in project root
$ cd ~/projects/my-project
$ python -m venv .venv

Project-local venvs are:

  • Easier to find and manage
  • Portable across machines
  • Standard for most Python tools

Mistake 4: Not Activating Before Installing Packages

terminal
# WRONG - Installs globally
$ pip install requests pandas
# (venv) prompt is missing!
# CORRECT - Activate first
$ source .venv/bin/activate
(.venv) $ pip install requests pandas
# BETTER - Use uv, never worry about activation
$ uv add requests pandas

With uv, this mistake becomes impossible. uv add always installs in the project’s virtual environment.

Mistake 5: Using Outdated virtualenv Instead of venv

terminal
# OLD WAY - Requires separate installation
$ pip install virtualenv
$ virtualenv .venv
# MODERN WAY - Built into Python 3.3+
$ python -m venv .venv
# BEST WAY - Let uv handle it
$ uv init my-project

The built-in venv module has been standard since Python 3.3. No need for a separate package.

Mistake 6: Wrong Python Version in venv

terminal
# Problem: venv uses default Python
$ python --version
Python 3.12.0
$ python -m venv .venv
# venv created with Python 3.12
# Solution: Specify Python version
$ python3.11 -m venv .venv
# venv created with Python 3.11
# With uv: Specify in pyproject.toml
$ uv init --python 3.11 my-project

VS Code Settings for Optimal venv Workflow

I added these settings to my .vscode/settings.json for automatic venv handling:

.vscode/settings.json
{
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
"python.terminal.activateEnvironment": true,
"python.analysis.typeCheckingMode": "basic",
"editor.formatOnSave": true,
"python.formatting.provider": "black"
}

What each setting does:

Settings Explained
defaultInterpreterPath: Tells VS Code where to find the venv Python
activateEnvironment: Auto-activates venv in new terminals
typeCheckingMode: Enables better IntelliSense and error detection
formatOnSave: Auto-formats code on save
formatting.provider: Uses Black for consistent code style

Fixing Common venv Problems

Problem: Packages Not Found After Installation

terminal
# Symptom: Installed package but can't import it
$ pip install requests
$ python -c "import requests"
ModuleNotFoundError: No module named 'requests'
# Diagnosis: Check which Python is active
$ which python
/usr/bin/python # Wrong! System Python, not venv
# Fix: Activate venv and reinstall
$ source .venv/bin/activate
(.venv) $ which python
/Users/me/project/.venv/bin/python # Correct!
(.venv) $ pip install requests

Problem: venv Created with Wrong Python Version

terminal
# Check venv Python version
$ source .venv/bin/activate
(.venv) $ python --version
Python 3.8.0 # But I need 3.11!
# Solution: Delete and recreate
$ deactivate
$ rm -rf .venv
$ python3.11 -m venv .venv
$ source .venv/bin/activate
(.venv) $ python --version
Python 3.11.0 # Correct!

Problem: Corrupted venv After System Update

terminal
# Symptom: Weird import errors or segfaults
$ python main.py
Segmentation fault (core dumped)
# Solution: Recreate from scratch
$ rm -rf .venv
$ python -m venv .venv
$ source .venv/bin/activate
(.venv) $ pip install -r requirements.txt

Why uv Is the Future

After reading the Reddit discussion, I realized why developers are switching to uv:

uv Advantages
1. Zero venv management - It just works
2. 10-100x faster than pip for package installation
3. Automatic lock files for reproducible builds
4. Cross-platform consistency (same commands everywhere)
5. No activation commands to remember
6. Built-in script dependency management (PEP 723)

The uv run command is the key insight:

terminal
# Instead of this dance:
$ source .venv/bin/activate
(.venv) $ python main.py
(.venv) $ deactivate
# Just do this:
$ uv run python main.py
# uv automatically:
# 1. Finds or creates the venv
# 2. Activates it internally
# 3. Runs your command
# 4. No cleanup needed

Migration Path

For existing projects with traditional venv:

terminal
# Option 1: Keep existing venv, use uv for new packages
cd existing-project
uv add new-package # Works with existing .venv
# Option 2: Migrate fully to uv
cd existing-project
uv init # Creates pyproject.toml
uv add $(pip freeze | cut -d= -f1) # Add all current packages
rm -rf .venv # Remove old venv
uv sync # Recreate with uv's management
# Option 3: Just use uv for dependency installation
uv pip install -r requirements.txt

Summary

The best Python virtual environment workflow in VS Code depends on your needs:

Workflow Recommendations
For new projects: Use uv (1-minute setup, zero maintenance)
For team projects: Use git-integrated venv + .gitignore (standard practice)
For quick scripts: Use uv run with inline dependencies
For existing projects: Migrate to uv or use VS Code auto-detection

The key settings for VS Code:

.vscode/settings.json
{
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
"python.terminal.activateEnvironment": true
}

And the key insight from the Reddit thread: virtual environment management should be invisible. If you’re spending time on venv setup, you’re not spending time on code.

After switching to uv, I’ve reclaimed those 10+ hours per year. More importantly, I’ve eliminated an entire category of “it works on my machine” errors. The workflow is now:

quickstart.sh
uv init my-project && cd my-project # Create project
uv add requests pandas # Add dependencies
uv run python main.py # Run code

Three commands. No activation. No debugging why packages aren’t found. Just code.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments