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

@forgrit/deploy-core

v0.1.0

Published

Provider-agnostic deployment primitives: result-shape types, failure taxonomy, health-probe classifier, retry-with-backoff helper. Zero runtime dependencies. Used by ForGrit and consumable by any deployment orchestrator.

Readme

@forgrit/deploy-core

Provider-agnostic deployment primitives: result-shape types, failure taxonomy, health-probe classifier, retry-with-backoff helper.

Zero runtime dependencies. Bring your own deployment provider.

Status

Early-access (v0.x). Breaking changes are permitted in minor version bumps until v1.0.0. Subscribe to CHANGELOG.md for migration notes.

What's in the box

Provider interface + result shapes

The three-method contract every deployment provider must implement:

import type { IDeploymentProvider, DeployParams, DeployResult } from '@forgrit/deploy-core';

class MyVercelProvider implements IDeploymentProvider {
  async deploy(params: DeployParams): Promise<DeployResult> {
    // call Vercel API, return { deploymentId, deployUrl, provider: 'vercel', status }
  }
  async getStatus(deploymentId: string) {
    // poll Vercel, return status snapshot
  }
  async teardown(deploymentId: string) {
    // call Vercel's delete API
  }
}

5-bucket failure taxonomy

Classify deployment errors into one of 5 buckets (config / code / infra / transient / unclassified). First-match-wins precedence. Battle-tested at ForGrit since Q1-2026.

import { classifyError } from '@forgrit/deploy-core';

classifyError('VERCEL_TOKEN expired'); // → 'config'
classifyError('TypeScript compile failed'); // → 'code'
classifyError('Provider returned 503'); // → 'infra'
classifyError('Rate limit exceeded'); // → 'transient'
classifyError('Some weird error we never saw'); // → 'unclassified'

The taxonomy also exports Postgres ILIKE helpers for SQL aggregation paths (buildIlikeCaseForBucket, buildUnclassifiedCase).

Health-probe failure classifier

Classify network errors caught during health probes:

import { classifyHealthProbeFailure, HealthProbeFailureReason } from '@forgrit/deploy-core';

try {
  await fetch(probeUrl, { signal: AbortSignal.timeout(5000) });
} catch (e) {
  const reason = classifyHealthProbeFailure(e);
  // → HealthProbeFailureReason.TIMEOUT | DNS | TLS | CONNECTION_REFUSED | NETWORK | HTTP_ERROR | UNKNOWN
}

Retry with exponential backoff

import { retryWithBackoff } from '@forgrit/deploy-core';

const result = await retryWithBackoff(() => fetch('https://provider-api.example.com'), {
  maxAttempts: 5,
  baseMs: 200,
  maxMs: 5000,
  shouldRetry: (err, attempt) => {
    // Don't retry caller bugs (4xx); do retry transient (429, 5xx, network)
    if (err instanceof Response && err.status >= 400 && err.status < 500 && err.status !== 429) {
      return false;
    }
    return true;
  },
  onRetry: (err, attempt, delayMs) => {
    logger.warn({ attempt, delayMs, err }, 'Retrying provider call');
  },
});

Why deploy-core?

ForGrit runs prompt-to-deployment generation at scale. The deploy-core package extracts the framework-agnostic primitives so any deployment orchestrator can adopt them — without taking on the apps/api NestJS dep graph.

Provider-specific adapters ship as separate sibling packages:

  • @forgrit/deploy-vercel — Vercel provider (plan #23a — coming soon)
  • @forgrit/deploy-neon — Neon Postgres database provisioner (plan #23b)
  • @forgrit/deploy-railway — Railway provider (plan #23c)

Each adapter depends on @forgrit/deploy-core for the shared interfaces + taxonomy. The IDeploymentProvider interface is the contract.

Why proprietary stays apps/api-local

Plan #23's investigation found ~5,324 LOC of deploy-related code in ForGrit's apps/api. Only ~176 LOC of that is genuinely framework-agnostic — the rest is tightly coupled to ForGrit's NestJS module graph, Prisma schema, and audit-log conventions. This package ships ONLY the framework-agnostic 176 LOC. The rest stays proprietary at apps/api-local.

See plan #22's close-via-reframing for the related "what stays proprietary" rationale (codegen orchestration).

Install

npm install @forgrit/deploy-core
# or
pnpm add @forgrit/deploy-core
# or
yarn add @forgrit/deploy-core

Engines

Node 20+.

License

MIT — see LICENSE.

Links