Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d248f9a
remove policy from original release guide
TimMonko Sep 1, 2026
fcdddf0
add release policy guide
TimMonko Sep 1, 2026
cf884b3
point from old release guide to policy
TimMonko Sep 1, 2026
a0d644d
update toc and dev index
TimMonko Sep 1, 2026
60f7804
add to core dev and triage guides
TimMonko Sep 1, 2026
7324583
adjust headers
TimMonko Sep 1, 2026
6ae9c3b
restore release manager timeline
TimMonko Sep 1, 2026
a180ae7
Apply suggestion from @Aniketsy
TimMonko Sep 1, 2026
0617b76
Apply suggestion from @Aniketsy
TimMonko Sep 2, 2026
27df04c
Apply batched suggestions from code review
TimMonko Sep 17, 2026
224acb7
fix core dev guide formatting
TimMonko Sep 21, 2026
3184596
respond to comments in release policy
TimMonko Sep 21, 2026
d2083b8
add deprecation policy
TimMonko Sep 21, 2026
189d407
add to _toc.yml
TimMonko Sep 21, 2026
3b9b0d0
link to throughout docs
TimMonko Sep 21, 2026
e0739d0
remove deprecation-guide mention
TimMonko Sep 21, 2026
dc47031
fix typo
TimMonko Sep 22, 2026
13a6148
add to core dev guide
TimMonko Sep 22, 2026
51c119a
add soft/hard to the contributing guidance
TimMonko Sep 22, 2026
ff13894
some updates addressing review
TimMonko Sep 22, 2026
979f55c
update soft deprecation guidance
TimMonko Sep 22, 2026
57e7a32
fix typo
TimMonko Sep 22, 2026
cb397ed
Merge branch 'main' into deprecation-policy
TimMonko Sep 22, 2026
14984d1
Merge branch 'main' of github.com:napari/docs into deprecation-policy
brisvag Oct 15, 2026
6ca306b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 15, 2026
a983d1a
Apply suggestion from @lundybernard
TimMonko Oct 15, 2026
ee81825
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/_toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ subtrees:
subtrees:
- entries:
- file: developers/coredev/release
- file: developers/coredev/deprecation_policy
- file: developers/coredev/packaging
- file: naps/index
subtrees:
Expand Down
7 changes: 4 additions & 3 deletions docs/community/mission_and_values.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ scientists** to use in their daily work. We hope to accomplish this by:

- providing a **consistent and stable API** to enable plugin developers to
build on top of napari without their code constantly breaking and to enable
advanced users to build out sophisticated Python workflows. Right now we are
still making breaking changes with minor version numbers `0.x` and do not
have a deprecation policy, but we will work to add one soon.
advanced users to build out sophisticated Python workflows. We follow a
formal [deprecation policy](napari-deprecation-policy), which commits us to
warning you in code and to publishing the window in which deprecated API may
be removed.

- ensuring **scientific accuracy**. We prioritise bug fixes and feature
development that affect the scientific interpretation of the displayed data.
Expand Down
13 changes: 9 additions & 4 deletions docs/developers/contributing/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,18 @@ Please also consider documenting any major features/changes in our

#### Deprecation Warnings

When deprecating a feature, use `FutureWarning` instead of
`DeprecationWarning`. `DeprecationWarning` is
Deprecating or changing existing API follows the [deprecation
policy](napari-deprecation-policy). When deprecating a feature, see the
policy for guidance on whether to use a soft (`DeprecationWarning`) or hard
(`FutureWarning`) deprecation, and how to set the removal window.
`FutureWarning` will be seen by end users, while `DeprecationWarning` is
[silenced by Python's default warning filters](https://docs.python.org/3/library/warnings.html#warning-categories),
making it invisible to library users.
Comment on lines +161 to 167

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth mentioninng that for some things we do want to use Deprecation warning, mainly for stuff that is "discouraged" but not planned to be removed yet (e.g: the viewer.scene.camera vs viewer.camera stuff we recently did).

This way, the deprecations will be seen by CI and by static type checkers, but will not spam GUI users.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally had a separate "how to do deprecations" file that I didn't include here -- mostly because I want to clean up napari/src first. So I missed this bit (as you see in the policy its mentioned). I'll make sure I properly mark the to-dos


**In the code**, always pass `stacklevel=2` to `warnings.warn()` so the warning
points to the caller's location rather than inside napari's internals.
**In the code**, by default, always pass `stacklevel=2` to `warnings.warn()`
so the warning points to the caller's location rather than inside napari's
internals. You may need to adjust the stacklevel if the warning is
emitted from a helper function or decorator.

In the docstring below the short summary, use the
[`.. deprecated::` directive](https://numpydoc.readthedocs.io/en/latest/format.html#deprecation-warning)
Expand Down
18 changes: 9 additions & 9 deletions docs/developers/coredev/core_dev_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,25 +87,25 @@ When reviewing, focus on the following:
provided through our plugin ecosystem. If in doubt, consult back with our
[mission and values](mission-and-values).

1. **Performance and benchmarks:** As `napari` targets scientific applications
2. **Performance and benchmarks:** As `napari` targets scientific applications
that often involve large multidimensional datasets, high performance is a
key value of `napari`. While every new feature won't scale equally to all
sizes of data, keeping in mind performance and our
[benchmarks](napari-benchmarks) during a review may be important, and you
may need to ask for benchmarks to be run and reported or new benchmarks to
be added.

1. **APIs and stability:** Coding users and plugin developers will make
3. **APIs and stability:** Coding users and plugin developers will make
extensive use of our APIs. The foundation of a healthy plugin ecosystem will
be a fully capable and stable set of APIs, so as `napari` matures it will
very important to ensure our APIs are stable. For now, while the project is
still in an earlier stage, spending the extra time to consider names of
public facing variables and methods, along side function signatures, could
save us considerable trouble in the future. Right now we are still making
breaking changes with minor version numbers `0.x` and do not have a
deprecation policy, but we will work to add one soon.
save us considerable trouble in the future. While pre-1.0 napari still makes
breaking changes in `0.x` version numbers, we follow a formal
[deprecation policy](napari-deprecation-policy).

1. **Documentation and tutorials:** All new methods should have appropriate doc
4. **Documentation and tutorials:** All new methods should have appropriate doc
strings following [PEP257](https://peps.python.org/pep-0257/) and the
[NumPy documentation guide](https://numpy.org/devdocs/dev/howto-docs.html#documentation-style).
For API changes, make sure to check that a `.. versionadded::` or
Expand All @@ -116,18 +116,18 @@ When reviewing, focus on the following:
[sentence case capitalization](https://apastyle.apa.org/style-grammar-guidelines/capitalization/sentence-case),
but the name `napari` should always be written in lowercase.

1. **Implementations and algorithms:** You should understand the code being
5. **Implementations and algorithms:** You should understand the code being
modified or added before approving it. (See
[Merge Only Changes You Understand](#merge-only-changes-you-understand)
below.) Implementations should do what they claim and be simple, readable,
and efficient in that order.

1. **Tests:** All contributions *must* be tested, and each added line of code
6. **Tests:** All contributions *must* be tested, and each added line of code
should be covered by at least one test. Good tests not only execute the
code, but explore corner cases. It can be tempting not to review tests, but
please do so.

1. **Labels and Milestones:** Make sure you add the appropriate labels and
7. **Labels and Milestones:** Make sure you add the appropriate labels and
milestone to PRs before merging. This should be done both in the main napari
repo and in the docs repo. Both repos have a CI check, triggered by the
`ready_to_merge` label, which will fail if the milestone is not set in the
Expand Down
192 changes: 192 additions & 0 deletions docs/developers/coredev/deprecation_policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
(napari-deprecation-policy)=

# Deprecation policy

This page states what napari promises when we change or remove public API, and
what plugin authors and downstream users can rely on.
This policy is about *notice*. It does not prevent napari from making breaking
changes — it commits us to telling you about them in advance, on a schedule you
can plan around.
Comment on lines +7 to +9

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a mention of how this stems from/relates to EffVer here would be good!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think I should move the EffVer section up that is two sections down? Or was this a comment from reading through in order.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think just a link would be nice :)


## What we promise

When napari changes or removes public API, we commit to:

1. **Warning you in code, where the runtime allows one.** Public API emits a
warning when it is used, in the category that matches its state (see
{ref}`napari-deprecation-states`). Some parts of the project cannot warn —
such as removals of support for a dependency — are announced in release
notes and socials and are given a removal window instead.
2. **Publishing the removal window.** Every deprecation states the earliest
window in which the API may be removed with search-friendly text.
3. **A minimum period of notice.** Two windows in most cases (see
{ref}`napari-deprecation-minimum-notice`).

## Relationship to versioning

napari uses [EffVer](https://effver.org) and ships on a monthly cadence; see
the [release policy](napari-release) for the full schedule. Under EffVer, a
deprecation is *not* tied to a particular release type, which is a deliberate
consequence of this policy: **time-based windows exist precisely so that notice
does not depend on whether the next release turns out to be `macro` or
`meso`.**

Removals still appear in release notes, and a release that removes deprecated
API is normally a larger-upgrade release, but you should not read a version
number as a promise about what was removed. Read the window instead.

(napari-deprecation-windows)=

## Deprecation windows

Deprecation windows are **quarters of a calendar year**, written as
`YYYY-QN` — for example `2027-Q2`. A window begins on:

| Window | Begins |
| --- | --- |
| `YYYY-Q1` | 1 January |
| `YYYY-Q2` | 1 April |
| `YYYY-Q3` | 1 July |
| `YYYY-Q4` | 1 October |

The format `YYYY-QN` should be used verbatim in the deprecation warning and in
the napari documentation, so a single search finds every deprecation and every
reference to a given window.

```{important}
A window is a **floor, not a ceiling**.

"May be removed as early as `2027-Q2`" means napari is permitted to remove the
API in any release from that window onward. It does **not** mean the API *will*
be removed in that window, and it does not mean the API will be removed at all.
If we choose not to remove something, we will re-window it (see
{ref}`napari-deprecation-lapsed`) rather than remove it quietly.
```

(napari-deprecation-minimum-notice)=

## Minimum notice

**Most deprecations get two windows** — if an API is deprecated during a given
quarter, it may first be removed from that quarter + 2, and thus is at least
six months of notice.

**Some deprecations get one window.** This is a fast track and it is only
available when a usage survey finds that plugins do not use the API in
question. See {ref}`napari-deprecation-survey`.

## What is covered

- **Public API** — anything documented in the [API reference](api) or
described in our [usage documentation](usage).
- **Some undocumented names that plugins use.** While napari discourages
developers from using private names, a few longstanding names are used by
plugins, like `viewer._qt_viewer`. We will try to be mindful of these paths
based on experience and issues opened by users and developers.
- **Behaviour and default changes.** If the *name* stays but the result
changes, the same window applies. This matters more than it may appear:
napari prioritises scientific accuracy, so a changed default can change what
a researcher sees in their data and therefore is as important, if not more
so, than a removed function because otherwise the change is silent.

(napari-deprecation-exempt)=

## What is exempt

The following do not go through this policy:

- **Security fixes.** A vulnerable or dangerously broken feature may be changed
or removed without notice.
- **Genuinely internal code** — private names that are not part of any
documented or plugin-facing API.
- **Features that never worked**, provided nothing depends on the broken
behaviour.
- **Features documented as experimental**, where the docstring says so. An
experimental marker has to actually be in the documentation; it cannot be
assumed.
- **Bug fixes that necessarily change behaviour.** These are exempt from the
window, but *not* from disclosure: the change must appear in the release
notes as a breaking change.

Judging whether a change is a bug fix or a breaking change is a judgement call.
We will make it in public, in the pull request, rather than silently.

## Dependency and platform support

Dropping support for a dependency or platform — a Qt binding, a Python version,
a NumPy version — cannot raise a `FutureWarning`, so it does not use a
deprecation warning. It does still get a **window**: support removals are
announced at least **two windows** ahead, so that a project which cannot move
immediately knows when it will be cut off. Supported versions of Python and
scientific python libraries follow, at minimum,
[SPEC 0](https://scientific-python.org/specs/spec-0000/).

(napari-deprecation-states)=

## Deprecation states

napari recognises two states. Which state an API is in determines
**which warning category** it emits, and that category is what decides who sees
it.

| State | Warning category | Who sees it | Window required? | Message must say |
| --- | --- | --- | --- | --- |
| **Hard** | `FutureWarning` | Everyone, including end users | **Yes** | "may be removed as early as `YYYY-QN`" |
| **Soft** | `DeprecationWarning` | Developers only | No | "there are no current plans to remove it" |

**Hard** states that an API is going away, and that it may be removed as early
as the window. **Soft** means an API we no longer recommend for new code but
**do not currently intend to remove**. Soft deprecations will show in multiple
places: including IDEs, pytest output, and when running with certain logging
configurations, but they are silenced by default for end users. Soft
deprecations are a way to signal that an API is not recommended for new code,
but that we are not yet ready to remove it. Soft deprecations may be promoted
to hard deprecations if we later decide to remove them.

### Moving between states

| Transition | Allowed | Consequence |
| --- | --- | --- |
| soft → hard | Yes | **The clock restarts** — a full minimum notice, counted from the promotion |
| hard → soft | Yes | Must be recorded with a reason, exactly as a re-window is |

(napari-deprecation-survey)=

## Usage surveys

Before selecting a window, a deprecation must be supported by evidence about
who uses the API. In practice this means searching the napari plugin ecosystem
for the symbol and linking the search in the pull request. This is the same
*impact assessment* step that
[NEP 23](https://numpy.org/neps/nep-0023-backwards-compatibility.html) requires
of NumPy deprecations.

The survey decides two things: whether the one-window fast track is available,
and which state is appropriate. An API that plugins use heavily is often a
better candidate for **soft** deprecation than for removal.

## How a deprecation is proposed

Deprecations are proposed like any other change, in a pull request, and
reviewed by the core team. A deprecation proposal should include:

- the API being deprecated and its replacement,
- the window, and the usage survey that justifies it,
- the state (hard or soft)

(napari-deprecation-lapsed)=

## When a window lapses

A window passing does not oblige anyone to act, but it does oblige someone to
*decide*. A window that has begun and has not been actioned is resolved at
release time in one of three ways:

1. **Remove it** and note the removal in the release notes.
2. **Re-window it** — declare a new window and record the reason. Re-windowing
is permitted and is not a failure; doing it silently is.
3. **Demote it** to a soft deprecation, if we have concluded it will not be
removed.

This process is meant to prevent a deprecation from being forgotten. It is not
meant to force a removal.
8 changes: 8 additions & 0 deletions docs/developers/coredev/release.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ include the following.
would be nice to merge before release.
- Look through currently open PRs and get a sense of what would be good to
merge before the first release candidate. Set milestones appropriately;
- Check for lapsed deprecation windows: search the source for removal windows
that have already begun, and resolve each one by removing the API,
re-windowing it with a recorded reason, or demoting it to a soft deprecation.
See the [deprecation policy](napari-deprecation-policy).

At this stage, bug fixes and features that are close to landing should be
prioritized. The release manager will follow up with PR authors, reviewing and
merging as needed. New features should wait until after release.

At this stage, bug fixes and features that are close to landing should be
prioritized. The release manager will follow up with PR authors, reviewing and
Expand Down
6 changes: 4 additions & 2 deletions docs/developers/coredev/release_policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ be in `MACRO.MESO.MICRO` versioning. This is similar to previous Semantic
Versioning schema of `MAJOR.MINOR.BUGFIX`, but allows features and bugfixes to
live harmoniously in any version. Instead, the version number implies to users
the amount of effort required to adopt the newest version from significant
effort (`MACRO`) to no expected effort (`MICRO`). Our current policy permits
deprecations in `MACRO` and `MESO` releases only.
effort (`MACRO`) to no expected effort (`MICRO`). Deprecations are permitted in
`MACRO` and `MESO` releases only and our time-based
[deprecation policy](napari-deprecation-policy) defines how and when deprecated
API is removed.

## Release cadence

Expand Down
Loading