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

@profullstack/sh1pt-target-deploy-ssh

v0.1.2

Published

Railway-style deploys to a server you own: git push in, a running app with a domain, TLS, a database and secrets out. No Docker, no Kubernetes, no PaaS. Code goes to the box over ssh, runs under systemd, and sits behind nginx.

Readme

deploy-ssh

Railway-style deploys to a server you own: git push in, a running app with a domain, TLS, a database and secrets out. No Docker, no Kubernetes, no PaaS. Code goes to the box over ssh, runs under systemd, and sits behind nginx.

  • Source: any git host the box can read (GitHub, GitLab, Codeberg, Gitea, your own git.example.com), or an rsync of your working tree.
  • Releases: ~/apps/<app>/releases/<id>, with current as a symlink. A deploy builds the new release while the old one keeps serving, then flips current atomically. If the health check fails, it flips back.
  • Runtime: a systemd unit running your start command, with bun installed automatically. Node works too, and static lets nginx serve files directly.
  • nginx + TLS: a site per app, with a Let's Encrypt certificate via certbot. Re-running is a no-op, and it never edits a site or unit it did not write.
  • Data: postgres: true creates a local role and database and sets DATABASE_URL; redis: true sets REDIS_URL.
  • Secrets: the vault keys you list are written to shared/app.env (0600). They travel over ssh stdin, never in argv.

The contract: bin/install.sh

The box-side work lives in your repo as an idempotent bin/install.sh (an OpenInstall script). This target runs it in each release with the phases setup, build and activate. A repo without one gets this generic copy. You can also run it by hand on any box:

git clone https://codeberg.org/me/myapp && cd myapp && ./bin/install.sh

Settings come from bin/install.conf (committed, no secrets), and the environment overrides them. The script header lists every key.

# bin/install.conf
PORT=3100
START_CMD=bun run start
DOMAINS=myapp.com www.myapp.com
POSTGRES=1

Manifest

targets: {
  prod: {
    use: 'deploy-ssh',
    config: {
      host: 'dev3.profullstack.com',
      user: 'anthony',
      app: 'myapp',
      // repo: defaults to your `origin`; ref: defaults to HEAD, which must be pushed
      env: ['STRIPE_SECRET_KEY', 'RESEND_API_KEY'],   // from the vault
      // Any bin/install.conf key can be set here instead:
      port: 3100,
      domains: ['myapp.com', 'www.myapp.com'],
      postgres: true,
    },
  },
},
sh1pt ship --target prod      # deploy HEAD

Other config: sshPort, sshKeyPath, source: 'rsync', dir (default apps/<app> under the user's home), keepReleases (default 5), vars (plain, non-secret env), runtime, install, build, start, healthPath, healthTimeout, tls, tlsEmail, staticDir, spa, redis, maxBody.

status() reports the current release, whether the unit is active and the health check result. rollback() returns to the release before the current one, with no rebuild.

What the box needs

  • An ssh key that works non-interactively (BatchMode=yes).
  • Passwordless sudo for the deploy user (systemd, nginx, certbot, apt).
  • For a private repo, a read-only deploy key on the box for your git host.
  • DNS for your domains already pointing at the box, so certbot can issue a certificate. Until then the site serves plain http, and the next deploy retries.

Development

pnpm vitest run packages/targets/deploy-ssh

The end-to-end test runs the real deploy-remote.sh and install.sh locally, against a throwaway git repo. It covers the first deploy, a second deploy, a broken release that is restored, rollback and pruning.