What does `pip install -e .` do that a plain `pip install .` does not?
answer
- Two installs, two very different results
- One copies the code, one points at it
- Something in site-packages redirects the import
- A .pth file or a generated finder
- PEP 660 editable wheel, no code copied
basics
~20 spip install -e . installs the project in editable mode: site-packages receives a pointer back to your working source tree instead of a copy of it, so a source edit takes effect on the next interpreter start without reinstalling.
solid answer
~40 s`pip install .` builds a wheel from the project and unpacks it into `site-packages`, so the environment then owns a frozen copy of the code and every later edit needs another install to be seen. `pip install -e .` runs the same build backend but asks it for an *editable* wheel under PEP 660: what lands in `site-packages` is metadata plus a redirection — typically a `.pth` file that adds your source directory to `sys.path`, or a `.pth` line that imports a small generated finder — so `import yourpkg` loads the file you are editing. It is still a real installation: the distribution shows up in `pip list`, its dependencies are resolved and installed, and `importlib.metadata.version()` can read its version. Editable mode is a development convenience; what you deploy should be the built wheel.
code
python · 5 linesimport importlib.util
spec = importlib.util.find_spec("json")
print(spec.origin)
print(spec.submodule_search_locations)go deeper
Be ready to state the difference in one sentence: a plain install copies your code into the environment, while pip install -e . points the environment at your source tree so edits take effect without reinstalling.
Explain the mechanics behind that sentence. The build backend still runs, but it produces an editable wheel whose payload is a redirection into your checkout plus ordinary .dist-info metadata, so dependency resolution and pip list behave exactly as normal.
Show judgement about where each belongs. Editable in development and local test runs; a built wheel in the packaging job and in production, so a module that was never declared fails there rather than in front of a user.
Own the policy across projects: which environments may use editable installs, where the real wheel gets exercised before release, and how you keep a developer's convenience from becoming the shape of the deployed artefact.
### Both commands go through the build backend `pip install .` and `pip install -e .` begin identically. pip reads `pyproject.toml`, looks at the `[build-system]` table, installs the declared build backend into an isolated build environment, and calls it. What differs is *which hook* pip asks for, and therefore what the resulting wheel contains. For a plain install pip asks the backend to build a normal wheel. A wheel is a zip file holding the importable package's `.py` files, any package data, and a `.dist-info` metadata directory. pip unpacks that into the environment's `site-packages`. From that moment the environment owns a private copy of your code, and the interpreter never looks at your source tree again — it looks at `site-packages`. That is exactly what a user gets when they install your project from an index, which is the value of a plain install: it exercises the real artefact. For an editable install pip asks the backend for an *editable* wheel, the hook standardised by PEP 660. The backend is free to decide how that wheel redirects imports, and the two common shapes are both tiny. The simplest writes a `.pth` file into `site-packages` whose single line is the absolute path of the directory containing your importable package; the `site` module reads every `.pth` in `site-packages` at interpreter start and appends such lines to `sys.path`, so `import yourpkg` resolves into your working tree. The stricter shape writes a `.pth` line that imports a generated module which registers a finder on `sys.meta_path`, mapping only the package names the project actually declares to their files on disk. Either way, the module source is never copied into the environment. ### An editable install is still an install This is the part candidates most often get wrong. An editable install is not a hack outside the packaging system. pip writes a normal `.dist-info` directory with `METADATA` and `RECORD`; the distribution appears in `pip list` and can be uninstalled; its declared dependencies are resolved and installed exactly as for any other install; another distribution that requires it is satisfied; `importlib.metadata.version("your-dist-name")` returns its version; and any console scripts it declares are generated into the environment's script directory. Because the install came from a local path, pip also records a `direct_url.json` in the `.dist-info` whose `dir_info` object carries `"editable": true`, which is how tooling can tell an editable install apart after the fact. ### The distribution and the importable package are different names Worth keeping straight while answering. The *distribution* is what pip installs and what `pip list` shows — the `name` in `[project]`. The *importable package* is the directory with `__init__.py` that `import` finds. They routinely differ in spelling, and an editable install is precisely the link between them: it teaches the environment that this distribution's importable package lives over there in your checkout. ### What "no reinstall needed" does not cover Only the module source is redirected. Metadata is snapshotted when you install, so adding a dependency, bumping the version, or declaring a new console script all need the install re-run. A compiled extension module still has to be rebuilt — editing its C source changes nothing until it is compiled. And a *running* interpreter caches imported modules in `sys.modules`; your edit is picked up by the next process, not by the one already executing. Development servers create the illusion of live editing by restarting the process for you. ### When to use which Use `-e` in a development environment and while running the test suite locally, where the whole point is a fast edit-run loop and where you want the tests to import the code the same way a user would. Use a built wheel everywhere the artefact matters: in a container image, in the packaging job of a pipeline, and in production. An editable install ties the environment to a working tree that may be dirty, may move, or may not exist on the target machine, and it hides a classic packaging bug — a module that imports fine because the whole source directory is on `sys.path`, but was never declared and so is missing from the real wheel. Building the wheel once and installing it is what surfaces that before a user does.
- Does an editable install still record the distribution's metadata and dependencies?Yes. pip writes a normal `.dist-info` directory with `METADATA` and `RECORD`, and for a local path install a `direct_url.json` whose `dir_info` marks the install editable. Dependencies are resolved and installed as usual, `importlib.metadata.version()` works, console scripts are generated, and another distribution that depends on this one is satisfied. Only the module files are redirected instead of copied.
- When would you deliberately install the built wheel instead of using `-e`?Whenever the artefact itself matters: container images, the packaging job in a pipeline, and production. An editable install makes the environment depend on a working tree that may be dirty, moved or absent, and it can hide a module that is importable only because the source directory sits on `sys.path` and was never declared for the wheel. Installing the wheel makes that fail where you can see it.
- You edited a module, but a long-running process still uses the old code. Why?Because an editable install redirects where imports *resolve*, not when they happen. A module already imported is cached in `sys.modules` and is not re-read; the edit takes effect the next time the process starts. Reloading is possible but does not rebind names that other modules already imported, which is why development servers restart the process instead.
A plain install files a photocopy of your project in the library; an editable install files a slip of paper saying the original is on that desk over there.
saying these in an interview costs you the question
- Says pip watches the filesystem and copies changed files
- Thinks -e skips the build backend entirely
- Believes an editable install is not a real install
- Claims an editable install cannot satisfy another package's dependency
- Recommends pip install -e for production deployments
- Expects edits to reach an already-running interpreter