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

deploydo

v3.0.2

Published

Deploy static files securely over SFTP, FTPS, or FTP

Readme

deploydo

Deploy static files over SFTP, FTPS, or FTP from a small, scriptable Node.js CLI.

Deploydo 3 is a security-focused major release: it uses modern transfer clients, validates configuration before connecting, supports CI-friendly credentials, and keeps a SHA-256 manifest to upload only changed files.

Requirements

  • Node.js 20 or newer
  • An SFTP, FTPS, or FTP server

Install

npm install --global deploydo

Quick start

Create a configuration template in the current project:

deploydo init

Edit deploydo.config.json, then validate it:

deploydo validate

Set the configured password variable and inspect the transfer without changing the server:

DEPLOYDO_PASSWORD='your-secret' deploydo deploy --dry-run

Run the deployment interactively, or use --yes --non-interactive in CI:

DEPLOYDO_PASSWORD='your-secret' deploydo deploy --profile default --yes --non-interactive

To enter a password once and reuse it on this computer, add --save-password to an interactive deployment. Deploydo saves it only after a successful connection:

deploydo deploy --profile production --save-password

deploydo --sample remains an alias for deploydo init.

Configuration

V3 prefers deploydo.config.json. The sourcePath is relative to the configuration file; remote paths always use POSIX separators.

{
  "profiles": {
    "production": {
      "protocol": "sftp",
      "host": "example.com",
      "port": 22,
      "username": "deploy",
      "sourcePath": "dist",
      "remotePath": "/var/www/html",
      "exclude": ["**/*.map"],
      "build": { "command": "npm run build" },
      "auth": {
        "passwordEnv": "DEPLOYDO_PRODUCTION_PASSWORD"
      },
      "sync": { "useManifest": true },
      "connection": { "retries": 2 }
    }
  }
}

Profiles support these fields:

| Field | Meaning | | --- | --- | | protocol | sftp, ftps, or ftp | | host, port, username | Server connection details; ports default to 22 for SFTP and 21 for FTP/explicit FTPS | | sourcePath, remotePath | Local source directory and remote target directory | | exclude | A glob or a list of globs to omit from the upload | | verbose | Print individual file operations; --verbose overrides it for one run | | build.command | Optional shell command run before a real deployment | | auth.passwordEnv | Environment variable containing the password | | auth.privateKeyPath | SFTP private key path, relative to the configuration file | | auth.privateKeyPassphraseEnv | Environment variable for the private-key passphrase | | auth.hostFingerprint | Optional SHA-256 host-key pin for SFTP | | sync.useManifest | Enables the changed-file manifest; enabled by default | | sync.manifestPath | Relative remote manifest name; defaults to deploydo.manifest.json | | connection.retries | Retry count for transient connection errors; defaults to 2 |

For FTPS, add an optional ftps block:

{
  "protocol": "ftps",
  "ftps": { "mode": "explicit", "rejectUnauthorized": true }
}

mode may be explicit or implicit; implicit FTPS defaults to port 990. Plain FTP remains available for old servers, but Deploydo warns because it does not encrypt credentials or transferred files.

Credentials and CI

Never put passwords in deploydo.config.json.

  • Use auth.passwordEnv for password authentication.
  • Use auth.privateKeyPath and auth.privateKeyPassphraseEnv for SFTP keys.
  • Use --password-stdin for a one-time pipeline secret. It requires --yes for a real deployment.
  • deploy --save-password stores the interactively entered password in the operating-system credential store after a successful connection. The next interactive deployment uses it automatically when no password environment variable is set. Environment variables and --password-stdin take priority.
  • Remove a stored password with deploydo credentials delete --profile <name>.
  • Deploydo only prompts on an interactive TTY. --non-interactive fails if a secret is missing.

On Windows this is Windows Credential Manager, on macOS the Keychain, and on Linux the Secret Service. No password is written to deploydo.config.json, the project directory, or a Deploydo-specific password file.

Example CI command:

deploydo deploy --profile production --yes --non-interactive --json

In JSON mode, stdout contains one final result object. Warnings and errors are written to stderr.

Synchronization and deletion

Deploydo scans regular files, including dotfiles such as .htaccess, and calculates SHA-256 hashes. A successful deploy writes a remote deploydo.manifest.json; unchanged files are skipped on later deploys. The default deliberately avoids a leading dot because some hardened FTP servers prohibit dot-file writes.

--dry-run reads the remote manifest but never uploads, deletes, or updates it. It also skips the configured build command by default.

--delete is deliberately conservative: it removes only paths from a previous Deploydo manifest that are no longer in the local source. It never mirrors or deletes arbitrary remote files.

Commands

deploydo deploy [--profile <name>|--env <name>] [--config <file>]
                 [--dry-run] [--delete] [--yes] [--no-build]
                 [--non-interactive] [--password-stdin] [--save-password] [--json]

deploydo validate [--profile <name>|--env <name>] [--config <file>] [--json]
deploydo credentials delete [--profile <name>|--env <name>] [--config <file>]
deploydo init [--output <file>] [--force]
deploydo migrate [--config <legacy-file>] [--output <file>] [--force]

Migrating V2

deploy.conf.json is still read as a legacy configuration and emits a warning. The legacy --env and --deployConfigFile flags remain available.

Create a V3 file without copying any passwords:

deploydo migrate --config deploy.conf.json

V2 source paths beginning with / retain their old working-directory-relative meaning while the legacy file is used. The generated V3 configuration converts such paths to the explicit relative form, for example /dist becomes dist.

Existing deploy.pw.conf.json files are ignored unless --allow-legacy-password-file is explicitly passed. This switch is intended as a short migration bridge only.

Development

npm test
npm run lint
npm run check
npm run pack:check

Run the protocol integrations locally with Docker:

npm run integration:up
DEPLOYDO_INTEGRATION=1 npm run test:integration
docker compose -f docker-compose.integration.yml down -v

The integration stack provides isolated SFTP, FTP, and explicit-FTPS servers. FTPS uses a self-signed certificate, so its test profile deliberately sets rejectUnauthorized to false; production profiles should keep the default of true.

Equivalent :rtk scripts are available in environments that use Rust Token Killer. The test suite covers configuration validation and migration, secrets, dotfiles, SHA-256 manifests, dry-runs, safe deletion, and failure exit paths.