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

@dodefey/deploy

v0.1.5

Published

A small, gunshi-based CLI app for deploying PM2 managed projects. Configurable with different deploy profiles. Runs test, build, syncs build to server and handles PM2 start/restart

Readme

@dodefey/deploy

A small gunshi-based CLI that deploys a profile-defined build managed by PM2. It runs tests, builds, syncs the client bundle to a remote host via rsync, restarts PM2, and reports client churn (cache reuse vs download impact) so you know the user-facing cost of a deploy. (Nuxt remains the common case, but the build command is now profile-configured.)

Features

  • Single command deploy pipeline: tests → build → rsync sync → PM2 restart → churn report.
  • Profile-driven config (profiles.json) with per-environment SSH, paths, build command/args, PM2 app name, and restart mode.
  • Typed error codes across build, sync, PM2, config, and churn for predictable handling.
  • Flexible output modes (inherit, silent, callbacks) for build/rsync/PM2 stages.
  • Dry-run mode: run build + churn and perform an rsync --dry-run; skip PM2 restart and make no remote writes.

Requirements

  • Node 20+ (ES2022 target, ESM).
  • SSH access to the target host; rsync and pm2 available on the server.
  • PM2 ecosystem file on the server (ecosystem.config.js) in remoteDir.

Installation

npm install
npm run build           # produces dist/ for the CLI binary

Run locally without install:

npx @dodefey/deploy --help

(After npm run build, the deploy bin points to dist/cli.js.)

Configuration (profiles.json)

Profiles live in your project root (./profiles.json). The CLI looks in the current working directory first; you can point to another file via the DEPLOY_PROFILES_PATH environment variable. Each profile sets connection and PM2 details.

[
	{
		"name": "prod",
		"sshConnectionString": "[email protected]",
		"remoteDir": "/var/www/app",
		"env": "production",
		"pm2AppName": "my-app",
		"buildCommand": "npx", // required
		"buildArgs": ["nuxt", "build", "--dotenv", ".env.production"], // required
		"buildDir": ".output", // optional, defaults to .output
		"pm2RestartMode": "startOrReload" // optional, defaults to startOrReload
	}
]

Validation rules:

  • Missing file / invalid JSON / empty array → CONFIG_PROFILE_FILE_NOT_FOUND.
  • Unknown profile name → CONFIG_PROFILE_NOT_FOUND.
  • Duplicate names → CONFIG_DUPLICATE_PROFILE.
  • Empty required fields (including buildCommand/buildArgs) → CONFIG_PROFILE_INVALID.
  • Invalid restart mode → CONFIG_INVALID_RESTART_MODE.

CLI Usage

Main command: deploy

Flags (from src/cli.ts):

  • --profile, -p <name> (required) Deploy profile from profiles.json to use.
  • --sshConnectionString, -s <ssh> Override SSH connection string.
  • --remoteDir, -d <path> Override remote app dir.
  • --buildDir, -b <path> Override local build output dir.
  • --env, -e <name> PM2 env.
  • --pm2AppName <name> PM2 app name override.
  • --pm2RestartMode <startOrReload|reboot> PM2 restart mode override.
  • --skipTests, -T Skip vitest before deploy.
  • --skipBuild, -k Skip build; reuse existing output in buildDir.
  • --dryRun, -n Run build + churn; rsync in --dry-run mode; skip PM2 restart (no remote writes).
  • --verbose, -V Inherit stdout/stderr from build/rsync/pm2.
  • --churnOnly, -c Compute churn without build/sync/pm2.

Example:

node dist/cli.js deploy \
  --profile prod \
  --sshConnectionString [email protected] \
  --remoteDir /var/www/app \
  --pm2AppName my-app \
  --pm2RestartMode startOrReload

Deploy Pipeline (what happens)

  1. Config: Load profile, apply CLI overrides, validate restart mode.
  2. Tests: vitest unless --skipTests.
  3. Build: Run the profile-defined build command (via runBuild); stdout mode per --verbose.
  4. Sync: rsync local .output to ${remoteDir}/.output (or override), honors --dryRun.
  5. PM2: pm2 startOrReload (or reboot) app in remoteDir; reports instance count.
  6. Churn: Compute client bundle churn vs previous manifest stored at ${remoteDir}/.deploy/manifest; uploads new manifest unless --dryRun.

Scripts

  • npm test → vitest
  • npm run lint → eslint
  • npm run build → tsc to dist/

Output Modes

outputMode is one of inherit (stream to terminal), silent, or callbacks (line handlers) and is used by build, sync, and PM2 modules.

Error Codes (selected)

  • Build: BUILD_COMMAND_NOT_FOUND, BUILD_FAILED
  • Sync: SYNC_NO_LOCAL_OUTPUT_DIR, SYNC_SSH_FAILED, SYNC_RSYNC_FAILED
  • PM2: PM2_SSH_FAILED, PM2_COMMAND_FAILED, PM2_STATUS_QUERY_FAILED, PM2_APP_NAME_NOT_FOUND
  • Config: CONFIG_PROFILE_FILE_NOT_FOUND, CONFIG_PROFILE_NOT_FOUND, CONFIG_PROFILE_INVALID, CONFIG_INVALID_RESTART_MODE
  • Churn: baseline load/parse failures, fetch failures

Troubleshooting

  • No profile found: ensure ./profiles.json exists in the directory where you run the CLI (or set DEPLOY_PROFILES_PATH) and that it has at least one profile with unique names.
  • PM2 app missing: check pm2AppName matches the ecosystem config on the server.
  • rsync errors: verify SSH connectivity and remote write permissions to ${remoteDir}/.output.
  • Churn baseline missing: first deploy will store a baseline manifest; subsequent runs compare against it.

License

MIT