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

@harly/cli

v0.4.0

Published

Official operations CLI for self-hosted Harly — guided install, day-2 management, and disaster recovery for the Docker Compose distribution.

Readme

@harly/cli

The official operations CLI for self-hosted Harly. A guided, auditable Node 20.12+ bootstrapper for immutable Docker Compose installs.

npx @harly/cli           # guided menu
npx @harly/cli check     # verify the host before installing
npx @harly/cli init      # generate a new installation
npx @harly/cli launch    # pull images and start the services
npx @harly/cli doctor    # check services and public readiness
npx @harly/cli update    # back up, upgrade, and migrate

Npm's name-similarity protections prevent an unscoped harly package. The scoped package still exposes the harly executable for global installs; with npx, use the concise official scope. A normal update is:

cd harly
npx @harly/cli update

Use --to edge for preview builds or --to <release-version> for a fixed release. The command creates a private local rollback point first, pulls the target, pins its immutable digest, runs migrations once, recreates the services, and waits for readiness. This works without extra system dependencies. Use --encrypt only when you have configured the optional advanced age backup encryption.

What it does

The interactive wizard runs a host preflight (Docker, ports, DNS, free disk, firewall) and detects the host's CPU/RAM to recommend a resource profile. It masks provider secrets and shows the complete installation plan before writing anything.

When something goes wrong, the CLI doesn't stop at a wall of text:

  • A busy port is identified by owner (nginx.service, traefik container, python3 (PID 1234)). The wizard offers to stop the service, switch to external-proxy mode, or pick a different port — and remembers the choice.
  • An unresolvable domain in interactive mode runs a 5-minute wait-and-retry loop so DNS propagation can finish on its own.
  • A missing Docker, an outdated Compose, an ufw rule that blocks 80/443, and a /setup flow that needs the HARLY_SETUP_SECRET all print a one-line cause plus the exact command to fix it.

Commands

| Command | Purpose | | --- | --- | | harly | Guided menu — install on a fresh host, or manage a detected installation. | | harly check [directory] | Verify the host (Docker, Compose, disk, free memory, firewall) without installing. | | harly init [directory] [--output-dir <directory>] | Generate a new installation. The positional directory and --output-dir are aliases; conflicting paths are rejected. | | harly launch [directory] [--yes] | Pull images and start the services, reporting per-service timing. | | harly doctor [directory] [--json] [--fix] | Check services and public readiness. --fix offers to restart the stopped ones. | | harly setup-secret [directory] | Print HARLY_SETUP_SECRET from .env — no need to open the file. | | harly backup [directory] [--encrypt] | Write a private local rollback archive. | | harly restore <archive> [directory] --force | Restore from an archive. | | harly update [directory] [--to version] | Back up, upgrade, and migrate. | | harly uninstall [directory] [--remove-data] | Stop and remove Harly. | | harly deploy <railway\|fly\|digitalocean> [prepare] | Deploy to Railway or prepare a Fly.io/DigitalOcean configuration. |

Resource profiles

The profile is chosen from the host's free memory minus Harly's known reservations (PostgreSQL, scheduler, Caddy, headroom), not from total RAM — a 4 GB VPS that already runs another service is not a "standard" candidate.

| Profile | Free RAM after reservations | Suggested use | | --- | --- | --- | | compact | < 1.5 GB | Trials and light traffic. | | standard | 1.5 – 3.5 GB | Small-team production. | | performance | 3.5 GB or more | Larger teams. |

Network requirements

For Caddy/automatic HTTPS, prepare a domain or preferably a subdomain (for example careers.example.com) whose DNS A record points to the VPS public IPv4 address. TCP ports 80 and 443 plus UDP 443 must be free; inbound TCP 80/443 (and UDP 443 for HTTP/3) must be allowed by the VPS firewall. If Nginx, Apache, Traefik, or another Caddy already owns those ports, select the external proxy mode and forward the hostname to 127.0.0.1:3000. The wizard checks DNS, classifies the process holding a conflicting port, and lets you fix it in place.

Automation

Global flags work before or after the subcommand when unambiguous: --json, --verbose, --non-interactive, --yes, --dry-run, --force, --timeout, and --no-color. --json disables prompts and loaders, writes one versioned JSON document to stdout for both success and failure, and sends optional human diagnostics to stderr.

For non-interactive use, pass configuration through environment variables. The required variables are listed by harly init when run without them. Public values such as --url, --domain, --email, and --resource-profile may be flags. Secrets are never accepted as flags. Use the environment or one explicit stdin source per invocation.

--url requires an origin with a protocol. --domain is a convenience alias that is normalized explicitly. --force only replaces generated non-secret files or an explicitly requested --save-env file after confirmation; it does not bypass safety checks or overwrite an existing installation blindly.

--dry-run --json resolves the plan and lists artifacts and remote operations without writing files, downloading images, or creating provider resources.

Railway does not write a local .env after deployment by default. Use --save-env explicitly to opt in; the file is written with mode 0600 and a warning is shown. Fly.io and DigitalOcean finish with ready-to-deploy and print the exact remaining provider commands. Successful self-hosted and Railway deployments finish with ready only after readiness checks pass.

Exit codes are 0 for success, 1 for operational failure, 2 for usage or configuration errors, and 130 for Ctrl+C. JSON responses use schemaVersion: 1 and stable error codes such as MISSING_SECRET, READINESS_TIMEOUT, and PARTIAL_PROVISIONING.

Secrets are generated independently per install, written only to .env with mode 0600, and never accepted as CLI arguments or emitted by any JSON result.

License

MIT — see LICENSE.