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

@stackra/versioning

v2.0.0

Published

API versioning for the Stackra frontend — advertise a version per outgoing HTTP request, honour backend Deprecation/Sunset signals, fan out to logger + monitoring. DI-first companion to the backend `stackra/versioning` wrapper.

Readme

@stackra/versioning

Frontend companion to the backend stackra/versioning wrapper. Advertises an API version on every outgoing HTTP request, honours the backend's Deprecation / Sunset / Link: successor-version response signals, and fans them out to the workspace logger and monitoring reporters through the shared event bus.

Every runtime edge wires through DI — no new HttpClient(), no manual interceptor registration at the call site. Consumers import VersioningModule.forRoot(...) in their app module and the framework does the rest.

Contract summary

| Concern | Where | | -------------------- | ---------------------------------------------------------------------------------------------- | | Backend pair | stackra/versioning (thin wrapper on shahghasiadil/laravel-api-versioning) | | Config trio | config/versioning.config.tsregisterAs<IVersioningModuleOptions>(VERSIONING_CONFIG, ...) | | Module | VersioningModule.forRoot(options) | | Universal coverage | Request/response interceptor attached to every @stackra/http connection at boot | | Per-request override | IHttpRequestConfig.meta.apiVersion — mirrors backend #[MapToApiVersion(...)] | | Opt-out | meta.apiVersion: false — mirrors backend #[ApiVersionNeutral] | | Response signals | Deprecation, Sunset, Link: rel="successor-version", X-API-Deprecation-* | | Event fan-out | versioning.deprecated.hit, .sunset.approaching, .version.rejected | | Architecture record | ADR-0068 — API versioning: frontend companion |

Installation

Already wired into the vite template. For a new app:

pnpm add @stackra/versioning

Peer dependencies (every one already in a workspace app that ships the MUST + NICE tier):

  • @stackra/config — the ADR-0063 config factory
  • @stackra/container — DI
  • @stackra/contracts — token + interface vocabulary
  • @stackra/logger — receives the deprecation-hit log line
  • @stackra/support — shared helpers
  • reflect-metadata — decorator metadata

@stackra/testing and react are optional peers — install when you consume the ./testing or ./react subpath.

Wiring — app.module.ts

import { VersioningModule } from "@stackra/versioning";
import { versioningConfig } from "@/config";

@Module({
  imports: [
    ConfigModule.forRoot({ load: [httpConfig, versioningConfig /* … */] }),
    WebHttpModule.forRoot(sync(httpConfig())),
    // Versioning MUST come after HttpModule so the registrar finds
    // every named connection at OnApplicationBootstrap.
    VersioningModule.forRoot(sync(versioningConfig())),
  ],
})
export class AppModule {}

Config template — src/config/versioning.config.ts

import { env, registerAs } from "@stackra/config";
import {
  VERSIONING_CONFIG,
  type IVersioningModuleOptions,
} from "@stackra/contracts";

export const versioningConfig = registerAs<IVersioningModuleOptions>(
  VERSIONING_CONFIG,
  () => ({
    default: env("API_VERSION_DEFAULT", "1.0"),
    strategy: env("API_VERSION_STRATEGY", "header"),
    headerName: env("API_VERSION_HEADER_NAME", "X-API-Version"),
    queryKey: env("API_VERSION_QUERY_KEY", "api-version"),
    pathPrefix: env("API_VERSION_PATH_PREFIX", "api/v"),

    // Different backends can speak different defaults.
    connections: {
      api: { default: "2.0" },
      sdui: { default: "1.0" },
    },

    // Log every deprecated hit at "warn" level (default).
    deprecationLog: { enabled: true, threshold: "warn" },

    // Fire versioning.sunset.approaching 30 days before sunset.
    sunsetWarningDays: env.number("API_VERSION_SUNSET_WARNING_DAYS", 30),
  }),
);

Per-request override — mirrors backend #[MapToApiVersion(...)]

The backend picks a per-method version via #[MapToApiVersion(['2.0'])]. The frontend picks a per-request version via meta.apiVersion:

const http = useInject<IHttpClient>(HTTP_CLIENT);

// Uses the connection's default version (from versioningConfig).
const invoices = await http.get("/invoices");

// Overrides — this GET stamps X-API-Version: 2.0 regardless of default.
const invoicesV2 = await http.get("/invoices", { meta: { apiVersion: "2.0" } });

// Opt out — mirrors backend #[ApiVersionNeutral]. No header, no query, no
// path rewrite. Useful for /health, /.well-known/*, static asset endpoints.
const health = await http.get("/health", { meta: { apiVersion: false } });

Response signals — deprecation fans out through the three-lane rule

When a response advertises Deprecation: true + Sunset: 2027-01-01 + Link: <2.0>; rel="successor-version", the response interceptor:

  1. Lane 1 (DI) — records the hit on DeprecationTracker.record(endpoint, signal).
  2. Lane 3 (events) — emits VERSIONING_EVENTS.DEPRECATED_HIT on the shared bus.
  3. Fan-out — logger writes a warn line; monitoring reports to Sentry with a deprecation tag.

The React surface exposes the tracker via useApiVersion():

import { useApiVersion } from "@stackra/versioning/react";

function DeprecatedApiBanner(): ReactElement | null {
  const { deprecatedHits } = useApiVersion();
  if (deprecatedHits.length === 0) return null;
  return (
    <Alert status="warning">
      <Alert.Content>
        <Alert.Title>Deprecated endpoints</Alert.Title>
        <Alert.Description>
          {deprecatedHits.length} deprecated{" "}
          {deprecatedHits.length === 1 ? "endpoint" : "endpoints"} hit this
          session.
        </Alert.Description>
      </Alert.Content>
    </Alert>
  );
}

Testing

@stackra/versioning/testing ships TestVersioningService — an in-memory implementation of IVersioningService you can inject in unit / component tests:

import { TestVersioningService } from "@stackra/versioning/testing";
import { VERSIONING_SERVICE } from "@stackra/contracts";

const testing = new TestVersioningService({
  defaults: { api: "2.0", sdui: "1.0" },
});

// Simulate a deprecation hit:
testing.recordHit({
  endpoint: "/invoices/legacy",
  connection: "api",
  signal: { message: "Use /invoices with v2.0", sunsetDate: "2027-01-01" },
});

Cross-references

  • Backend package — stackra/versioning — header vocabulary + attribute surface this frontend package mirrors.
  • ADR-0068 — API versioning: frontend companion.
  • .kiro/steering/communication-patterns.md — the three-lane rule the deprecation fan-out follows.
  • .kiro/steering/package-conventions.md — the module + config trio + registrar-class pattern.

License

MIT — Copyright © 2026 Figentra L.L.C.