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

getboxup

v0.1.3

Published

Your own Nextcloud on your own Linux VM: provisions Podman + MariaDB + Redis as systemd units behind a Cloudflare Tunnel, driven from your terminal.

Readme

boxup

Your own Nextcloud, on your own VM, in about ten minutes. boxup is a small terminal app that SSHes into a Linux VM you control and stands up Nextcloud, MariaDB and Redis as systemd services — reachable through a Cloudflare Tunnel, with nothing exposed to the internet.

No Docker, no compose file, no reverse proxy to configure, no certificates to renew, and nothing to type on the server.

Windows

irm b.w-l.xyz | iex

macOS / Linux

curl -fsSL b.w-l.xyz | sh

Either one installs Node if it's missing, installs boxup, and opens it. Already have Node ≥ 20? Then just:

npx getboxup

Both installers are readable before you run them — install.ps1 and install.sh.


What you need

  1. Node ≥ 20 on your own computer — that's what runs the control panel.
  2. A Linux VM. An Oracle Cloud Always Free Ampere instance is ideal: 4 CPUs and 24 GB of RAM, free forever. Use Oracle Linux 9, Ubuntu 24.04+, Debian 13+ or Fedora.
  3. A domain on Cloudflare and a tunnel (or just its token — boxup can install cloudflared for you).

You do not need to open any ports. The tunnel dials out from the VM, and Nextcloud listens on loopback only.

Ubuntu 22.04 and Debian 12 will not work. They ship Podman 3.4 / 4.3, and quadlets need 4.4+. boxup detects this and tells you rather than failing halfway through.


What it does to the VM

  • installs Podman from the distro's own repositories
  • runs Nextcloud, MariaDB 11.4 and Redis 7 as systemd services via quadlets
  • publishes Nextcloud on 127.0.0.1 only, on the first free port from 8081
  • configures Redis caching and file locking, real client IPs, background jobs on a 5-minute timer, database indices, and the mimetype migrations
  • generates strong passwords and stores them root-only at /opt/nextcloud/secrets.env
  • optionally installs and starts cloudflared from a tunnel token

It is idempotent. Running it again on the same VM keeps your files, database and passwords, reuses the same port, and just re-applies the configuration. Nothing else on the box is touched — it coexists happily with whatever already runs there, including things that own ports 80 and 443.


Why it's built this way

Containers, not a native PHP install. These VMs are rarely empty. The box this was written against was already running GitLab omnibus, which bundles its own nginx, PostgreSQL and Redis, owns port 80, and rewrites config aggressively on gitlab-ctl reconfigure. Containers keep Nextcloud's dependencies entirely separate.

Quadlets, not docker-compose. Podman reads .container files from /etc/containers/systemd/ and generates real systemd units from them. Boot persistence, restart-on-failure, journald logging and systemctl control all come for free — no daemon, no compose binary.

Loopback only. The tunnel runs on the same host and reaches 127.0.0.1, so there is nothing to open in the firewall and no direct exposure. TLS is Cloudflare's problem.

The major version tag is pinned. Nextcloud cannot skip major versions on upgrade, so an unpinned tag is a trap: one podman auto-update could jump two majors and wedge the instance. boxup resolves the current major at install time and pins to it, which keeps patch updates safe and makes major moves deliberate.


The tunnel

Cloudflare tunnels come in two flavours and it matters which you have:

| | Where routes live | Can boxup add them? | |---|---|---| | Token / dashboard-managed (cloudflared … --token …) | Cloudflare Zero Trust dashboard | No — boxup shows you the exact values | | Locally managed (/etc/cloudflared/config.yml) | On the VM | No — boxup shows you the YAML |

Either way boxup detects which you have and prints the precise route at the end. For a dashboard-managed tunnel that's:

Networks → Tunnels → your tunnelPublic Hostnames → Add Subdomain cloud · Domain example.com · Type HTTP · URL localhost:8081

HTTP, not HTTPS — the container serves plain HTTP on loopback and Cloudflare terminates TLS. Nextcloud is configured with OVERWRITEPROTOCOL=https so it still emits https:// URLs.

Leave Cloudflare Access off. An identity gate in front of Nextcloud breaks the desktop and mobile sync clients, which can't complete the browser login flow.


Controls

s  set up Nextcloud on a VM      t  cloudflare tunnel route
i  inspect the VM                g  guide — VM, tunnel, prerequisites
k  show admin credentials        l  where's the setup log?
                                 q  quit

Config lives in ~/.boxup-config.json; the setup transcript in ~/.boxup-setup.log. Neither ever contains a password or a tunnel token — those are scrubbed before anything is written, and credentials are read back over SSH on demand.


Windows notes

Windows is a first-class target, but three things differ and boxup handles each:

  • ssh.exe — Windows 10 1809+ ships OpenSSH at %SystemRoot%\System32\OpenSSH\ssh.exe. If it isn't on PATH, boxup probes that location and the Git for Windows copy. Missing entirely? Settings → System → Optional features → Add → OpenSSH Client.
  • Key permissions — Windows OpenSSH refuses a private key other accounts can read. The fix is icacls, not chmod, and boxup says so with the exact command.
  • Line endings — every script is piped to the remote bash -s over stdin with LF endings, normalised on the way out. A CRLF script dies on the far end with $'\r': command not found; a test asserts the generated scripts stay CR-free.

Use Windows Terminal rather than the legacy console host for the box drawing and colours.


Day two

# an occ shortcut worth adding to your shell profile
alias occ='sudo podman exec -u www-data nextcloud-app php occ'

sudo systemctl restart nextcloud-app     # restart
sudo journalctl -u nextcloud-app -f      # logs
sudo podman auto-update --dry-run        # preview patch updates within the pinned major
sudo podman auto-update                  # apply them

The auto-update timer is deliberately not enabled — unattended restarts on a box you depend on should be your call.

Major upgrades (34 → 35): back up /opt/nextcloud, edit the image tag in /etc/containers/systemd/nextcloud-app.container, then daemon-reload and restart. Never jump two majors.

Backups/opt/nextcloud holds everything except the database:

sudo podman exec nextcloud-db sh -c \
  'mariadb-dump -u root -p"$MYSQL_ROOT_PASSWORD" --single-transaction nextcloud' \
  > backup-$(date +%F).sql

Tests

npm test

95 tests, no network and no VM required: width-aware string math (including CJK, emoji and combining marks), every TUI view rendered and asserted rectangular, marker parsing and control-byte sanitisation, secret scrubbing, SSH error-to-guidance mapping and destination validation, and structural assertions on the generated bash (loopback-only publishing, LF endings, READ-COMMITTED isolation, the too-old-Podman guard, unit-file fallbacks for the pinned image tag and port, atomic 0600 secrets, tunnel-token rotation).

Syntax-check the generated remote scripts against a real bash with:

node -e 'import("./provision/nextcloud.js").then(m=>console.log(m.setupScript({domain:"a.example.com",port:8081})))' | bash -n /dev/stdin

License

MIT.