CLI and SDK for ShipStatic — deploy static websites, landing pages, and prototypes instantly from the terminal or code.
npm install -g @shipstatic/shipAs a project dependency:
npm install @shipstatic/ship
ship ./distYour site is live instantly on *.shipstatic.com. No API key, no sign-up, no configuration.
Deployments without an API key are public and expire in 3 days. The output includes a claim URL — visit it to keep the site permanently.
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 permanentlyFor 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 promptedconst ship = new Ship({ apiKey: 'ship-...' });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)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.comship.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 supportedship 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)ship whoami
ship config
ship pingship.account.get() // → whoami
ship.ping() // → boolean
ship.getConfig() // → platform config and plan limits (cached)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 {} -qship completion install
ship completion uninstall| Flag | Description |
|---|---|
--api-key <key> |
API key for authenticated requests |
--deploy-token <token> |
Deploy token for single-use deployments |
--config <file> |
Custom config file path |
--label <label> |
Add label (repeatable) |
--no-path-detect |
Disable automatic path optimization |
--no-spa-detect |
Disable automatic SPA detection |
--no-color |
Disable colored output |
--json |
Output results in JSON format |
-q, --quiet |
Output only the resource identifier |
--version |
Show version information |
// No credentials — deploy only, 3-day expiry
const ship = new Ship();
// API key — permanent, full access
const ship = new Ship({ apiKey: 'ship-...' });
// Deploy token — single-use, consumed on successful deploy
const ship = new Ship({ deployToken: 'token-...' });
// Set credentials after construction
ship.setApiKey('ship-...');
ship.setDeployToken('token-...');ship.deploy(input, {
labels?: string[],
onProgress?: ({ percent }) => void,
signal?: AbortSignal,
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
apiKey?: string, // Per-request API key override
deployToken?: string, // Per-request deploy token override
});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>']) }
]);ship.on('request', (url, init) => {});
ship.on('response', (response, url) => {});
ship.on('error', (error, url) => {});
ship.off('request', handler);import { isShipError } from '@shipstatic/types';
try {
await ship.deploy('./dist');
} catch (error) {
if (isShipError(error)) {
error.isAuthError();
error.isValidationError();
error.isNetworkError();
}
}Resolved in order of precedence:
- Constructor options:
new Ship({ apiUrl, apiKey }) - Environment variables:
SHIP_API_URL,SHIP_API_KEY - Config files:
.shiprcorpackage.json"ship"key
SHIP_API_KEY=ship-... ship deployments listimport type { ShipClientOptions, DeploymentOptions, ShipEvents } from '@shipstatic/ship';
import type { Deployment, Domain, Account, StaticFile } from '@shipstatic/types';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.