npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@utility-kit/deprecated

v0.1.0

Published

Framework-agnostic deprecation utility with configurable labels, environment-aware alerts, and optional telemetry hooks. Zero dependencies.

Readme

@utility-kit/deprecated

A framework-agnostic deprecation utility. Mark old APIs as deprecated with a single function call — get environment-aware logging, dev-only browser alerts, structured migration messages, and optional telemetry, with zero dependencies.

Install

npm install @utility-kit/deprecated

Why

Most "deprecate this function" helpers hard-code console.warn and call it a day. This one is a primitive: you plug in your own environment flags (dev/prod, browser/server) and telemetry sink, and it stays consistent across every app, package, and framework in your stack.

  • Zero dependencies, fully tree-shakeable
  • Works in Node, browsers, and edge runtimes — you decide what "dev" and "browser" mean
  • Throws by default (fail loud in tests/CI), or downgrade to a warning per call-site
  • Every user-facing string is overridable
  • Optional onDeprecated hook for analytics/telemetry pipelines

Usage

import { createDeprecated } from "@utility-kit/deprecated";

const deprecated = createDeprecated({
  env: {
    isDev: process.env.NODE_ENV !== "production",
    isBrowser: typeof window !== "undefined"
  }
});

function oldBookingApi() {
  deprecated("oldBookingApi() is deprecated", {
    since: "v2.4.0",
    until: "v3.0.0",
    alternative: "createBooking()",
    path: "src/legacy/booking.ts"
  });
  // ...
}

By default, calling deprecated() throws. This is intentional: deprecations should be loud enough to fail a test or crash a dev build, not quietly scroll past in a log. Use warnOnly where a hard throw isn't appropriate (e.g. production runtime paths you can't break):

deprecated("oldBookingApi() is deprecated", {
  warnOnly: true,
  alternative: "createBooking()"
});
// logs via console.warn instead of throwing

SvelteKit example

import { browser, dev } from "$app/environment";
import { createDeprecated } from "@utility-kit/deprecated";

export const deprecated = createDeprecated({
  env: { isDev: dev, isBrowser: browser },
  onDeprecated: ({ message, severity }) => {
    analytics.track("deprecated_api_used", { message, severity });
  }
});

Next.js / generic browser example

export const deprecated = createDeprecated({
  env: {
    isDev: process.env.NODE_ENV === "development",
    isBrowser: typeof window !== "undefined"
  }
});

API

createDeprecated(config)

Returns a deprecated(message, options?) function bound to your environment and labels.

config

| Field | Type | Description | |---|---|---| | env.isDev | boolean | Enables console.error logging and (if isBrowser) a browser alert(). | | env.isBrowser | boolean | Enables the alert() in dev. Ignored outside dev. | | labels | Partial<DeprecatedLabels> | Override any user-facing string. Shallow-merged with defaults. | | onDeprecated | (payload) => void | Fired on every call, before throwing/warning. Use for telemetry. |

deprecated(message, options?)

| Option | Type | Description | |---|---|---| | path | string | File, module, or endpoint where the deprecation originates. Appended as [Origin]. | | since | string | When it was deprecated (e.g. "v2.4.0"). Appended as part of [Lifecycle]. | | until | string | When it will be removed. Appended as part of [Lifecycle]. | | alternative | string | Suggested replacement API. Appended as [Migration]. | | warnOnly | boolean | Downgrade from throwing to console.warn. Default false. | | devMessage | string | Replaces the built message in the dev console.error log only — the thrown/warned message is unaffected. | | meta | Record<string, unknown> | Extra data passed straight through to console.warn/console.error and the onDeprecated payload. |

Behavior:

  • Default (warnOnly unset): throws an Error containing the built message.
  • warnOnly: true: logs via console.warn and returns undefined instead of throwing.
  • env.isDev: true: additionally logs via console.error (using devMessage if provided), regardless of warnOnly.
  • env.isDev: true and env.isBrowser: true: additionally calls globalThis.alert() if it exists.
  • onDeprecated, if provided, always fires with { message, options, severity } before the throw/return.

DEFAULT_LABELS

The default label set, exported so you can reference or partially extend it instead of retyping everything.

Design notes

  • No global state. Every createDeprecated() call returns an independent handler — call it once per app/package and export the instance, or create scoped instances per module.
  • No auto-detection. isDev/isBrowser are passed in explicitly. This package doesn't guess based on process.env or typeof window, so it works identically in bundlers, edge runtimes, and test environments.
  • Message building is deterministic. Lifecycle → Migration → Origin, always in that order, only including the parts you provide.

License

MIT