venv creates virtual environments using the Python interpreter that runs it. It ships with CPython, though some Linux distributions require an extra package before it can install pip. virtualenv is a separate tool with interpreter discovery, cached environment creation, more activation scripts, and plugins.
Choose based on how you select Python versions, how often you recreate environments, and which tools already manage them. Vercel installs production dependencies from your committed dependency files, so either tool works for local development.
Copy link to headingHow to compare venv vs. virtualenv
The Python Packaging Authority lists both as standard tools for manually creating virtual environments. They differ in interpreter selection, repeated setup, activation scripts, and integration APIs.
Copy link to headingvenv vs. virtualenv at a glance
pip, editors, and test runners can use environments created by either tool. To reproduce application behavior, match the Python interpreter, installed packages, and configuration.
Copy link to headingSelect the Python interpreter explicitly
A machine may have Python installations from the operating system, Homebrew, pyenv, or another version manager. The interpreter you select determines which language features and package builds you can use.
venv uses the interpreter that runs it. If Python 3.11 is installed as python3.11, python3.11 -m venv .venv creates a 3.11 environment.
virtualenv accepts an interpreter path, name, or version constraint through -p. On a machine whose default is 3.12, virtualenv -p 3.11 .venv can find an installed Python 3.11 without changing the default. Quote version ranges, as in virtualenv -p ">=3.12" .venv, so the shell does not treat > as output redirection.
virtualenv also resolves pyenv, mise, and asdf shims to the underlying Python binary. It selects an available interpreter and does not install missing versions. The interpreter selection guide documents the supported arguments.
Copy link to headingCompare repeated setup with the same cache conditions
Repeated environment creation adds work to continuous integration, or CI, jobs and test matrices. Part of that work is seeding, which installs the initial package-management tools.
venv bootstraps pip through ensurepip for each new environment unless you pass --without-pip. virtualenv's default app-data seeder builds install images on first use. Later environments link or copy those images instead of installing the seed packages through pip again.
The virtualenv documentation reports shorter seeding times with a warm cache. These are the project's own measurements, and the results depend on the seeding method and platform. Separate CI jobs must preserve or restore the app-data cache to reuse its images.
Compare both tools on the same runner with the same interpreter and seed packages. Measure cold-cache and warm-cache creation separately.
Copy link to headingCheck which activation scripts your shell needs
Activation puts an environment's executable directory first on PATH. Each shell needs a compatible activation script. You can also call the environment's Python directly without activation.
venv includes activation scripts for bash and zsh, fish, csh/tcsh, PowerShell, and cmd.exe. PowerShell activation is available on Windows and through pwsh on macOS and Linux.
virtualenv adds Nushell and xonsh activators, along with activate_this.py. That script changes import paths and environment variables inside a running Python process. It does not replace the process's interpreter. Both tools supply activation scripts for bash, zsh, fish, and PowerShell.
Copy link to headingMatch the API to the integration
Test runners and integrated development environments, or IDEs, may create environments from Python code. Some integrations need to customize creation steps or inspect an environment before creating it.
venv provides create() and an EnvBuilder class. You can subclass EnvBuilder to change setup steps, but venv has no plugin system. virtualenv provides cli_run() and session_via_cli(). The first creates an environment. The second describes a creation session without building it. Its plugin hooks cover discovery, creation, seeding, and activation through package entry points declared in pyproject.toml.
You rarely need these APIs when writing a project's setup commands. They let tools customize environment creation from Python code.
Copy link to headingCheck what your test runner and editor already use
tox and Nox use virtualenv by default. Both let you configure a different backend. Nox exposes --default-venv-backend to change its default.
Poetry declares virtualenv as a dependency, and PyCharm bundles it. Hatch's virtual environment backend uses virtualenv and pip by default. Setting installer = "uv" switches environment creation and package installation to uv.
VS Code's Python Environments extension supports venv creation and can use uv automatically when it is available. Selecting the "venv" environment type does not guarantee that the editor runs python -m venv.
A project can document python -m venv .venv for development, while its test suite uses virtualenv. Check each tool's backend settings before changing the setup.
Copy link to headingHow to evaluate venv for project environments
Python Enhancement Proposal 405, or PEP 405, introduced venv in CPython 3.3. The separate pyvenv script was the recommended entry point in 3.3 and 3.4. From 3.5 onward, the docs recommend invoking the module directly. Python 3.8 removed the script.
Python 3.6 added --prompt to customize the environment's shell prompt. Python 3.9 added --upgrade-deps to fetch the latest pip from PyPI. Python 3.12 stopped installing setuptools into new environments. Projects that need setuptools must declare or install it explicitly. Read more in the CPython venv documentation.
Copy link to headingUnderstand what venv creates
Running python -m venv .venv creates an environment directory containing:
pyvenv.cfg, which records the base Python installation.binon macOS and Linux, orScriptson Windows, which holds the environment's Python executable and installed commands. On macOS and Linux, the executable is a copy or symlink to the base interpreter. Current CPython installations on Windows use a small redirector by default.lib/pythonX.Y/site-packages, orLib\site-packageson Windows, for installed packages.
Unless you pass --without-pip, the command bootstraps pip from the wheels supplied with the Python distribution. The environment still depends on its base Python installation. Recreate it as needed rather than treating it as a portable Python installation.
Copy link to headingBalance venv's advantages against its limits
venv's advantages come from shipping with Python:
No separate environment tool on most installations. Some distributions require an extra package for pip bootstrapping.
Offline creation. With the required distribution packages and wheels installed, creation does not need a network request.
--upgrade-depsfetches newer packages from PyPI.Git ignore files since Python 3.13. New environments include a
.gitignorecovering their contents unless you pass--without-scm-ignore-files. It helps prevent accidental commits, though you can still override it.Updates through Python. Fixes and options arrive with CPython releases. There is no separate environment-builder package to upgrade.
Consider these limits:
External interpreter selection. To create both 3.11 and 3.12 environments, invoke each interpreter's
venvmodule.Repeated pip bootstrapping. New environments run
ensurepipby default. venv has no install-image cache like virtualenv's, so measure the cost on your CI runner.Fewer activators. venv does not include Nushell, xonsh, or
activate_this.py. You can still use its environments from any shell by calling their executables directly.Distribution-specific setup. Debian and Ubuntu may require
python3-venvor the package matching the selected Python version before pip bootstrapping works.
If python points to the wrong interpreter, venv creates an environment with that version. Check the result with .venv/bin/python --version, or .venv\Scripts\python.exe --version on Windows. The output should show the version you intended.
Best fit. venv suits projects that explicitly select their interpreter and do not require extra activators or plugins. This includes single-runtime apps and multi-version workflows in which the runner already selects each Python version.
Pricing. venv is free as part of CPython. Some distributions require an extra package installation.
Copy link to headingCreate an environment in a container
When the base image already supplies venv and pip bootstrapping, these Dockerfile instructions create an environment and put its commands on PATH:
RUN python -m venv /opt/venvENV PATH="/opt/venv/bin:$PATH"Later Python and pip commands use the environment at /opt/venv. If the image packages venv support separately, install those operating-system packages first. Creating the environment can work offline. Installing the project's dependencies also requires local copies of the packages or a reachable package index.
This also suits air-gapped or locked-down runners whose Python installation already includes the required venv packages and wheels. For new contributors, using the bundled tool removes a separate environment-builder installation from onboarding.
venv added --copies in Python 3.4 and also supports --symlinks. You do not need virtualenv solely to copy the interpreter into an environment.
Copy link to headingHow to evaluate virtualenv for repeated and customized setup
virtualenv adds interpreter discovery, cached seeding, and plugins to environment creation. It requires Python 3.9 or later to run. Its compatibility reference lists CPython 3.9 through 3.15 and PyPy 3.9 through 3.11 on Linux, macOS, and Windows. GraalPy 24.1 or later has experimental support on Linux and macOS.
By default, each run discovers an interpreter, builds the environment, installs pip, and writes activation scripts. virtualenv normally uses its own creator. If it has no built-in creator for the target interpreter, it falls back to the standard library's venv creator.
Copy link to headingBalance virtualenv's advantages against its limits
The main advantages are:
Interpreter discovery.
-paccepts a path, name, or version constraint and resolves supported version-manager shims. One virtualenv installation can create environments for several supported Python interpreters already on the machine.Reusable seed images. A warm app-data cache avoids rebuilding the same install images for each environment. CI jobs need access to that cache to reuse images across runs.
More activators. virtualenv includes Nushell and xonsh scripts.
activate_this.pymakes the environment's packages available to a compatible running Python process.Plugins and a Python API. Discovery, creation, seeding, and activation hooks let integrations customize setup.
cli_run()andsession_via_cli()let Python code create or inspect environments.
Account for these limits:
A separate installation. Install virtualenv with pipx, a suitable package manager, or another method in its installation guide. Fresh CI images need that step unless they already include the tool.
Host and target version limits. Release 21.5.0 dropped Python 3.8 support. Older interpreters may require an older virtualenv release or their own
venvmodule.Cache and seed-package state. virtualenv bundles seed-package wheels and maintains an app-data cache. By default, it checks for eligible wheel updates at 14-day intervals.
--reset-app-dataresets the cache.--no-periodic-updatedisables automatic checks.An independent release cycle. virtualenv releases can bundle newer pip versions. Pinning virtualenv controls builder upgrades. To reproduce environments, also control the Python version, seed packages, and project dependencies.
The virtualenv installation guide covers the available methods. If you already have pipx, run pipx install virtualenv, then check the installed version with virtualenv --version.
Best fit. Use virtualenv for interpreter discovery, repeated creation with a reusable cache, custom creation plugins, or more activators.
Pricing. virtualenv is free and open source under the MIT license.
Copy link to headingBuild a test matrix with tox
tox can build one environment per interpreter and run the same test commands in each. It uses virtualenv by default. You can keep using venv for development while tox creates the test environments.
For an existing tox.ini configuration, the version matrix belongs under [tox]:
[tox]env_list = py311, py312, py313
[testenv]deps = pytestcommands = pytestWith those interpreters installed and tests available, running tox creates the three environments, installs the project and pytest, and runs the tests in each. The project must be installable as a Python package. If it has no packaging metadata, add skip_install = true under [testenv].
Current tox documentation recommends TOML for new configurations. The same example in tox.toml is:
env_list = ["3.11", "3.12", "3.13"]
[env_run_base]deps = ["pytest"]commands = [["pytest"]]The tox tutorial explains both formats. tox can reuse existing environments between test runs. virtualenv's seed cache helps when tox creates new ones.
Copy link to headingHow to choose venv or virtualenv for your team
Check who selects each Python interpreter and how often the team recreates environments. Then check whether you need plugins or activation scripts beyond those venv supplies.
Copy link to headingChoose venv when interpreter selection is already handled
venv usually covers an app with one deployed Python version and one development environment per contributor. It also works across multiple Python versions when a CI matrix or test runner explicitly invokes each interpreter.
If you create one environment and keep it for the project's lifetime, cached creation offers little benefit. virtualenv's discovery, plugins, or extra activators may still be useful.
Document the required Python version, any distribution-specific packages, and the shell's activation command. A version declaration in .python-version or pyproject.toml does not make python -m venv select that interpreter on its own.
Copy link to headingChoose virtualenv for discovery, caching, or extensions
Use virtualenv when you need to find installed interpreters by version, reuse seed images across repeated creation, or customize creation through plugins. It also supplies activation scripts for Nushell and xonsh.
For libraries that support several Python versions, check the test runner's default before adding setup commands. tox or Nox may already supply virtualenv.
Copy link to headingConsider uv when environment and package management belong together
uv is written in Rust, while venv and virtualenv are Python-based tools. It creates environments, installs packages, and manages project lockfiles.
uv venv creates .venv. uv venv --python 3.12 requests a specific version. If that version is missing, uv can download it when its settings and network access allow. Its environment guide explains how to create and use environments.
virtualenv remains an option when a workflow requires a Python-based builder, its plugin system, or a test-runner integration that already uses it.
uv does not install pip into a new environment by default. Use equivalent seeding settings when comparing creation times, and measure the full setup process if performance determines your choice.
Switching a local setup to uv does not change tox or Nox's backend. Configure those tools separately if they should use it.
Copy link to headingHow to use local Python environments with Vercel
Your local environment supplies packages during development. Vercel builds from the dependency declarations and Python version settings you commit.
Copy link to headingKeep production dependencies in the repository
Vercel CLI excludes .venv, venv, and __pycache__ from uploads by default. Python builds use uv as the default package manager during dependency installation. When it introduced uv, Vercel reported 30% to 65% faster builds.
Declare dependencies in pyproject.toml with or without uv.lock, requirements.txt, or a Pipfile with its corresponding Pipfile.lock. A package installed locally becomes a production dependency only when the build's dependency files or configuration include it.
Copy link to headingRun the app locally with vercel dev
Vercel's FastAPI guide, Flask guide, and Django guide use venv for local setup and vercel dev to serve the app.
With Vercel CLI installed, a supported Python version available, and dependencies in requirements.txt, run these commands in bash or zsh:
python -m venv .venvsource .venv/bin/activatepip install -r requirements.txtvercel devThese commands create and activate the environment, then install dependencies. vercel dev starts the local development server and prints its URL. Follow the framework guide for app files, CLI requirements, and configuration.
On Windows PowerShell, use the corresponding activation path:
python -m venv .venv.\.venv\Scripts\Activate.ps1pip install -r requirements.txtvercel devPowerShell's execution policy can affect activation. You can install into the environment without activation by calling .\.venv\Scripts\python.exe -m pip directly. If your project uses another dependency format, replace the requirements-file installation step with its documented command.
Copy link to headingMatch local Python to the deployment version
Different Python versions can change language or dependency behavior. Vercel reads the Python version setting from requires-python in pyproject.toml, .python-version, or Pipfile.lock.
Vercel supports Python 3.12 (default), 3.13, and 3.14. To constrain deployment to Python 3.12.x, add this field to the existing [project] section of pyproject.toml:
[project]requires-python = "~=3.12.0"Create the local environment with virtualenv -p 3.12 .venv or python3.12 -m venv .venv. Check the resulting version separately. The deployment setting does not switch an existing local environment's interpreter.
Copy link to headingKeep test tooling out of the function bundle
A project can use virtualenv through tox or Nox without including those tools in production. Vercel's Python runtime guidance recommends listing only runtime packages in the dependencies installed for the function.
Keep test tooling in a separate file such as requirements-dev.txt and leave that file out of the production installation command. For test directories and fixtures, configure excludeFiles under the relevant functions entry in vercel.json. Removing a package from runtime dependencies does not exclude project files from the bundle.
Copy link to headingHow Vercel handles Python deployment
Either tool can create a local development environment. Vercel deploys the app using the project's dependency files, runtime settings, and application entrypoint.
Vercel handles these parts of deployment:
Large functions. The public beta supports uncompressed Python bundles up to 5 GB, compared with the standard 500 MB limit. It requires Fluid compute with Active CPU enabled. New projects are eligible by default. Existing projects can opt in with
VERCEL_SUPPORT_LARGE_FUNCTIONS=1. The beta applies when a function exceeds the standard size limit and does not support projects using Secure Compute or Static IPs.Python framework presets. Vercel detects supported frameworks such as FastAPI, Flask, and Django from dependency declarations. Define a supported entrypoint so the runtime can load the application and route requests to it.
uv-powered builds. uv is the default package manager for dependency installation during Python builds.
Python version settings. Set a supported version in
.python-version,pyproject.toml, orPipfile.lock, then create a matching local environment explicitly.Local development.
vercel devruns supported Python apps locally. The framework guides provide venv-based setup commands and required CLI versions.
You can start a new project to deploy your Python app or browse templates for a FastAPI, Flask, or Django starter.
Copy link to headingFrequently asked questions about venv vs virtualenv
Copy link to headingDo you still need virtualenv if Python includes venv?
venv covers environment creation for each Python interpreter you invoke. Use virtualenv if you need interpreter discovery, cached seeding, plugins, or more activators.
You may also use it through a test runner or editor. python -m pip show virtualenv reports whether it is installed in that interpreter's environment. It does not establish which tool installed it or find copies in other isolated tool environments.
Copy link to headingCan you move a virtual environment to another directory?
Recreate it at the destination. Activation scripts and installed entry points can contain absolute paths, and the environment depends on a base Python installation. The venv documentation treats environments as disposable and not generally movable or copyable.
Keep dependency declarations in version control and recreate the environment from them. Keep the environment directory itself out of Git.
Copy link to headingWhy does venv fail on Debian or Ubuntu?
An error containing ensurepip is not available can mean the selected Python installation lacks the package required for pip bootstrapping. Install python3-venv for the distribution's default Python, or a matching versioned package, such as python3.12-venv when available. Then recreate the environment.
For the default system Python, the command is:
sudo apt install python3-venvAfter installation, python3 -m venv .venv should create the environment with pip available. --without-pip skips bootstrapping when your workflow installs packages another way.
Copy link to headingIs venv faster if you skip pip installation?
venv --without-pip removes pip bootstrapping from creation. To compare creation without seed packages, measure it against virtualenv --no-seed using the same interpreter and machine.
For environments that need pip, include seeding in both measurements and distinguish cold-cache from warm-cache runs. Measure the setup your project will use.