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

@shipstatic/ship

v1.0.2

Published

SDK & CLI for ShipStatic platform

Readme

@shipstatic/ship

CLI and SDK for ShipStatic — deploy static websites, landing pages, and prototypes instantly from the terminal or code.

Deploy in seconds — no install, no account

npx @shipstatic/ship ./dist

That's it. Your site is live on *.shipstatic.com. No sign-up, no config, no global install. Got Node? You're ready.

The output includes a claim URL — visit it to keep the site permanently. Anonymous deployments are public and expire in 3 days.

import Ship from '@shipstatic/ship';

const ship = new Ship();
const result = await ship.deploy('./dist');
// result.deployment → live URL (happy-cat-abc1234.shipstatic.com)
// result.claim      → visit to keep permanently

Install (optional, for repeat use)

npm install -g @shipstatic/ship   # global CLI — drop the `npx @shipstatic/ship` prefix

As a project dependency: npm install @shipstatic/ship

Every example in this README uses the bare ship command. If you haven't installed it globally, prefix any of them with npx @shipstatic/ship (or npx -y @shipstatic/ship in non-interactive environments).

All Commands — Free API Key

For permanent deployments and full control over your sites and domains, get a free API key from my.shipstatic.com/api-key.

ship config    # paste your API key when prompted
const ship = new Ship({ apiKey: 'ship-...' });

Deployments

ship ./dist                                        # Deploy (shortcut)
ship ./dist --label production --label v1.0.0      # Deploy with labels
ship deployments list
ship deployments get <deployment>
ship deployments set <deployment> --label production
ship deployments remove <deployment>
ship.deploy(input, options?)               // Shortcut for deployments.upload()
ship.deployments.upload(input, options?)
ship.deployments.list()
ship.deployments.get(deployment)
ship.deployments.set(deployment, { labels })
ship.deployments.remove(deployment)

Domains

ship domains set www.example.com                   # Reserve domain (no deployment yet)
ship domains set www.example.com <deployment>      # Link domain to deployment
ship domains set www.example.com --label prod      # Update labels only
ship domains get www.example.com
ship domains list
ship domains validate www.example.com
ship domains verify www.example.com
ship domains records www.example.com
ship domains dns www.example.com
ship domains share www.example.com
ship domains remove www.example.com
ship.domains.set(name, { deployment?, labels? })   // Upsert — create, repoint, or label
ship.domains.get(name)
ship.domains.list()
ship.domains.validate(name)
ship.domains.verify(name)
ship.domains.records(name)
ship.domains.dns(name)
ship.domains.share(name)
ship.domains.remove(name)

domains.set() is a merge-upsert — omitted fields are preserved on update, defaulted on create. Once linked, a domain cannot be unlinked ({ deployment: null } → 400). Switch deployments or delete the domain instead.

Domain names are normalized by the API — any case, Unicode accepted:

ship.domains.set('WWW.Example.COM');   // → www.example.com
ship.domains.set('www.münchen.de');    // → Unicode supported

Tokens

ship tokens create --ttl 3600 --label ci
ship tokens list
ship tokens remove <token>
ship.tokens.create({ ttl?, labels? })
ship.tokens.list()
ship.tokens.remove(token)

Account

ship whoami
ship config
ship ping
ship.account.get()            // → whoami
ship.ping()                   // → boolean
ship.getLimits()              // → platform plan limits (cached)

CLI Reference

Composability

The -q flag outputs only the resource identifier — perfect for piping and scripting:

# Deploy and link domain in one pipe
ship ./dist -q | ship domains set www.example.com

# Deploy and open in browser
open https://$(ship ./dist -q)

# Batch remove all deployments
ship deployments list -q | xargs -I{} ship deployments remove {} -q

Shell Completion

ship completion install
ship completion uninstall

Global Flags

Available on every command:

| Flag | Description | |------|-------------| | --api-key <key> | API key for authenticated requests | | --deploy-token <token> | Deploy token for authenticated deployments | | --api-url <url> | API URL override (for development) | | --config <file> | Custom config file path | | --json | Output results in JSON format | | -q, --quiet | Output only the resource identifier | | --no-color | Disable colored output | | --help | Display help for command | | --version | Show version information |

Deploy Flags

Available on ship <path> and ship deployments upload:

| Flag | Description | |------|-------------| | --label <label> | Add label (repeatable) | | --password <password> | Password-protect this deployment (6–128 chars) | | --no-path-detect | Disable automatic path optimization | | --no-spa-detect | Disable automatic SPA detection |

CLI Environment Variables

| Var | Purpose | |---|---| | SHIP_API_KEY | Default for --api-key | | SHIP_DEPLOY_TOKEN | Default for --deploy-token | | SHIP_API_URL | Default for --api-url | | SHIP_PASSWORD | Default for --password (empty string normalized to absence) |

SDK Reference

Authentication

// No credentials — deploy only, 3-day expiry
const ship = new Ship();

// API key — permanent, full access
const ship = new Ship({ apiKey: 'ship-...' });

// Deploy token — scoped to deploys, optional TTL, revocable
const ship = new Ship({ deployToken: 'token-...' });

// Set credentials after construction
ship.setApiKey('ship-...');
ship.setDeployToken('token-...');

Deploy Options

ship.deploy(input, {
  labels?: string[],
  password?: string,          // Password-protect the deployment (6–128 chars)
  onProgress?: ({ percent }) => void,
  signal?: AbortSignal,
  onCancel?: () => void,      // Called if signal aborts
  pathDetect?: boolean,       // Auto-optimize paths (default: true)
  spaDetect?: boolean,        // Auto-detect SPA (default: true)
  maxConcurrency?: number,    // Concurrent uploads (default: 4)
  timeout?: number,           // Request timeout in ms
  via?: string,               // Client identifier
  apiUrl?: string,            // Per-request API URL override
  apiKey?: string,            // Per-request API key override
  deployToken?: string,       // Per-request deploy token override
});

Password protection

Pass password (6–128 characters) to gate the deployment behind a prompt. Visitors are asked for the password before they can view the site, including on any custom domains pointing at it. To remove protection, redeploy without a password.

ship --password 'your-passphrase' ./dist
await ship.deploy('./dist', { password: 'your-passphrase' });

The CLI also reads SHIP_PASSWORD from the environment when --password is not given.

Browser Usage

import Ship from '@shipstatic/ship';

const ship = new Ship({ apiKey: 'ship-...' });

// From file input
const deployment = await ship.deploy(fileInput.files);

// From StaticFile array
const deployment = await ship.deploy([
  { path: 'index.html', content: new Blob(['<html>…</html>']) }
]);

Events

ship.on('request', (url, init) => {});
ship.on('response', (response, url) => {});
ship.on('error', (error, url) => {});
ship.off('request', handler);

Custom fetch

Pass fetch to override the transport function used for every API call. Defaults to globalThis.fetch. Useful for wrapping requests with tracing, retries, or request signing, and for injecting a Cloudflare service-binding Fetcher from a Worker so calls reach a sibling Worker in-process instead of through the public hostname.

import type { Fetch } from '@shipstatic/ship';

const traced: Fetch = (input, init) =>
  globalThis.fetch(input, { ...init, headers: { ...init?.headers, 'X-Trace-Id': 'abc-123' } });

const ship = new Ship({ fetch: traced });
// Cloudflare Worker with a service binding to the API.
// Any parseable apiUrl works — service bindings dispatch by binding identity, not hostname.
const ship = new Ship({
  apiUrl: 'https://api',
  fetch: env.API.fetch.bind(env.API),
});

Error Handling

import { isShipError, ErrorType } from '@shipstatic/types';

try {
  await ship.deploy('./dist');
} catch (error) {
  if (isShipError(error)) {
    error.isAuthError();        // semantic category
    error.isNetworkError();     // semantic category
    error.isClientError();      // semantic category (Business | Config | File | Validation)
    error.type === ErrorType.Validation;  // specific-type check
    error.status === 429;       // status check
  }
}

Configuration

The CLI (ship) resolves credentials in this order:

  1. CLI flags: --api-key, --api-url, --deploy-token
  2. Environment variables: SHIP_API_KEY, SHIP_API_URL, SHIP_DEPLOY_TOKEN
  3. Config files: .shiprc or package.json "ship" key (run ship config to create one)

The SDK (new Ship(...)) resolves credentials in this order:

  1. Constructor options: new Ship({ apiUrl, apiKey })
  2. Environment variables: SHIP_API_KEY, SHIP_API_URL, SHIP_DEPLOY_TOKEN

The SDK never reads .shiprc or package.json — file resolution is a CLI feature, not an SDK feature. This keeps new Ship({}) safe to use from embedded contexts (MCP, n8n, library wrappers) without inheriting the host developer's personal credentials.

SHIP_API_KEY=ship-... ship deployments list

TypeScript

import type { ShipClientOptions, DeploymentOptions, ShipEvents } from '@shipstatic/ship';
import type { Deployment, Domain, Account, StaticFile } from '@shipstatic/types';

AI Agents

This package includes a SKILL.md file — a portable skill definition that AI agents (Claude Code, Codex, etc.) use to deploy sites with ship autonomously.


Part of the ShipStatic platform.