R1.05.3deprecation windowdesign

Deprecation needs an explicit date or release, not a comment

Aliases: deprecation date · removal target · sunset schedule · @deprecated

What it is

@deprecated in source and “discouraged” in the docs are suggestions under delivery pressure, and suggestions are ignored. Deprecation needs a schedulable window: gone in a named release, or gone after a calendar day. The window turns “someday” into a planning object — calendars, a CI fail date, a remaining-call-site board all get an anchor.

Without a clock, deprecated APIs live forever and new ones never fully replace them. This is not the design of the path across, and not the structural question of whether two implementations should coexist. It is when the old name is allowed to disappear.

Why it happens

Consumers trade against deadlines. With no date, migration loses to features, because features have external promises and deprecation has only an internal wish. Marking deprecated without a removal point also trains people to mute static checks: the warning was there on day one, still there on day thirty, so it becomes wallpaper. A window uses time to create scarcity: after this release the old export leaves the types, CI goes red, and the schedule has a counterparty.

The window also has to be visible outside a comment and not movable by hallway talk. “Next major” in a JSDoc has no handle on a consumer’s calendar; the same fact in the release notes, the migration guide, and the package’s deprecation metadata lets tools start counting before the window closes. Slipping the date requires a new announcement, not a chat message pushing the removal — or the window is a wish again.

Where it stops holding

Emergency removals for a security hole or a legal demand may be shorter than the usual window, but they still get a date, even if the date is “the hotfix day,” broadcast on every consumer channel. An experimental export that never shipped can skip the window and be deleted, provided it never appeared in stable-channel types. APIs frozen by an external standard (payment field names) may need a window measured in years; a short one would force consumers to break the law or drop charges — the clock still exists, the ticks are longer. An internal monorepo that can delete every call site in one commit may shrink the window to that commit, but the merge note must still say “gone as of now,” or people on branches will assume the old name remains.

Applying it

  • Every deprecation writes three anchors: the release that introduces the warning, the target release or calendar day of deletion, and the person who owns remaining call sites inside the window.
  • Encode the deletion day in package metadata and CI: after the window, the old export leaves the types and leftover references must fail, not keep warning.
  • Publish the remaining-call-site count on a cadence. If it has not dropped by halfway, escalate to a blocker rather than quietly sliding the deletion day.
  • How to check: open the deprecation note and read a concrete release identifier or date; then confirm CI flips from warning to error at that point. A comment with no date and no fail day is still a wish.

Related

  • Same group: R1.05.1 A breaking change needs a migration path · R1.05.2 Shipping multiple versions in parallel collapses consistency
  • Nearby: R1.13 Versioning and migration cost · R1.06 Contribution process and governance
  • Search terms: deprecation window · removal date · deprecated without clock

Cards in the same group

Quick Actions

Share

Share this page

ios_share

https://hci.top/en/handbook/R1.05.3