Install & Compatibility
Where this runs
tested against v0.8.2 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.910 runs
installs and imports cleanly · install 0.0s · import 1.233s · 49.4MB
glibcpy 3.10–3.910 runs
installs and imports cleanly · install 5.5s · import 1.119s · 50MB
49MB installed
● package 49MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
PluginManager
✓ from npe2 import PluginManager
Manifest
✓ from npe2.manifest import Manifest
Primarily used by plugin developers to create or manipulate manifest objects directly, less common for general users.
napari_plugin_manager
✓ from napari.plugins.manager import napari_plugin_manager
This is napari's primary interface for its plugin system, which internally uses npe2. Often the preferred way to interact with plugins when napari is running.
This quickstart demonstrates how to initialize the npe2 PluginManager, discover available plugins (including npe1 plugins), and then inspect the contributions provided by a specific plugin. It shows how the engine itself can be used to query the plugin ecosystem.
from npe2 import PluginManager
pm = PluginManager.instance() # Get the singleton PluginManager instance
# Discover all plugins, including older npe1 plugins if present
pm.discover(include_npe1=True)
print(f"Discovered {len(pm.plugins)} plugin packages.")
# Example: List contributions from a specific plugin (e.g., 'napari-svg')
# This assumes 'napari-svg' is installed and has contributions
if "napari-svg" in pm.plugins:
print(f"\nContributions from napari-svg:")
for contribution_type in pm.get_plugin_contributions("napari-svg"):
contributions = pm.get_plugin_contributions("napari-svg")[contribution_type]
if contributions:
print(f" {contribution_type}: {list(contributions.keys())}")
else:
print("\nnapari-svg not found or has no contributions. Try another installed plugin.")
npe2 --version
Debug
Known issues
breakingMigration from npe1 (legacy) to npe2 (modern) requires significant changes for plugin developers. npe2 introduces a manifest-based plugin declaration system, replacing the implicit `napari_` prefixed package discovery of npe1. Plugins developed for npe1 will not be discovered or function correctly under npe2 without migration.fixPlugin developers must create a `napari.yaml` manifest file and update `pyproject.toml` or `setup.cfg` with a `napari.plugin` entry point. Refer to npe2 migration guides and the `napari` plugin tutorial for details.
affects: All napari versions using npe2 (typically napari>=0.4.16).
gotchanpe2 plugin discovery is explicit and relies on correctly configured package entry points and `napari.yaml` manifests. If a plugin's `pyproject.toml` or `setup.cfg` is not correctly configured, or if the `napari.yaml` manifest is missing or malformed, the plugin will not be found by the PluginManager.fixVerify that your plugin's `pyproject.toml` (or `setup.cfg`) contains a `[project.entry-points."napari.plugin"]` entry pointing to a valid `napari.yaml` file relative to your package root. Ensure the plugin package is correctly installed.
affects: All npe2 versions.
gotchaThe `PluginManager.discover()` method has an `include_npe1` argument (default `False` when called directly). If this is not set to `True`, older `npe1` plugins will not be discovered by the standalone `npe2.PluginManager`. Note that `napari`'s internal plugin manager often sets this to `True` for compatibility.fixIf you need to discover and interact with legacy `npe1` plugins directly through `npe2.PluginManager`, ensure you call `pm.discover(include_npe1=True)`.
affects: All npe2 versions.
Errors
Common errors & fixes
KeyError: 'Plugin "my-plugin" not found'
The specified plugin's manifest could not be discovered or loaded by the `npe2.PluginManager`. This often means the plugin is not correctly installed or its entry points are misconfigured.
fix1. Ensure the plugin package is installed (`pip install my-plugin`). 2. Verify the plugin's `pyproject.toml` (or `setup.cfg`) has a correct `[project.entry-points."napari.plugin"]` entry pointing to its `napari.yaml` manifest. 3. Ensure the `napari.yaml` file exists at the specified relative path.
FileNotFoundError: [Errno 2] No such file or directory: '/path/to/my_plugin/napari.yaml'
The path specified in the `napari.plugin` entry point (in `pyproject.toml` or `setup.cfg`) does not match the actual location of the `napari.yaml` manifest file within the installed plugin package.
fixCheck the `napari.plugin` entry point configuration to ensure the path is correct relative to the package root, and that the `napari.yaml` file is present in the plugin's source and installed package.
TypeError: 'str' object is not callable
You are likely trying to directly call a string identifier (e.g., a `command_id` or `function_id`) instead of the actual Python callable it represents. `npe2` contributions are often registered as identifiers.
fixUse the `PluginManager`'s methods to retrieve and execute the actual callable. For example, use `pm.execute_command("my-plugin.my_command_id", **kwargs)` or `pm.get_function_contributions("my-plugin")` to get the functions. Upgrade
Version history
0.8.2latest on PyPI · released Apr 4, 2026
Audit
Dependencies
naparirequirednpe2 is the plugin engine for napari. While npe2 itself doesn't directly depend on napari for its core logic, it is meaningless without a napari environment to provide and consume plugins. Most users interact with npe2 through napari.