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

uptool

v0.2.0

Published

Serve LLM-generated HTML files via wildcard subdomains on your own domain

Downloads

172

Readme

uptool

Serve LLM-generated HTML files from your own machine via wildcard subdomains.

Your LLM runs uptool deploy → gets back a URL → you open it anywhere.

LLM writes dashboard.html
LLM runs: uptool deploy dashboard.html
LLM says: ✓ http://x7k2mq.mydev.com  (expires in 72h)
You open it on your phone, tablet, or any browser

No cloud service. No third-party uploads. Your machine, your domain.


Install

npm install -g uptool
# or use without installing:
npx uptool <command>

Manual installation (from source)

Build and install from the repository — useful for trying unreleased changes or contributing:

# 1. Clone
git clone https://github.com/pyeom/uptool.git
cd uptool

# 2. Install dependencies
npm install

# 3. Build (compiles src/ → dist/cli.js)
npm run build

# 4a. Link it as a global `uptool` command…
npm link

# 4b. …or run directly without linking:
node dist/cli.js <command>

Verify it works:

uptool --version

To remove a linked build later:

npm unlink -g uptool

Requires Node.js ≥ 18.


Prerequisites

You need:

  1. A domain you control (e.g. mydev.com)
  2. A wildcard DNS record pointing to your machine:
    *.mydev.com  →  A  →  <your machine's public IP>
  3. Port forwarding on your router: port 3000 (or whichever you configure) → your machine

No static IP? Use Cloudflare Tunnel — free, no port forwarding needed.


Setup

uptool init

Walks you through configuration and writes ~/.uptool/config.toml:

base_url = "mydev.com"
port = 3000        # public HTTP server
api_port = 3001    # internal API (localhost only)
ttl = "72h"        # file expiry — 0 = never
storage_path = "~/.uptool/files"

# Optional
rate_limit_rpm = 0     # per-IP requests/min on the public server (0 = off)
trust_proxy = false    # read X-Forwarded-For for client IP (only behind a proxy you control)
# cert_file = "/path/fullchain.pem"   # enables HTTPS when set with key_file
# key_file  = "/path/privkey.pem"

Usage

Start the server

uptool serve

Starts as a background daemon. Logs go to ~/.uptool/server.log.

Deploy a file

uptool deploy dashboard.html
# ✓ http://x7k2mq.mydev.com  (expires in 72h)

Deploy from stdin

cat output.html | uptool deploy
# or pipe directly from a script
echo "<h1>Hello</h1>" | uptool deploy

LLM output wrapped in markdown fences is handled automatically:

```html
<h1>Hello</h1>

→ strips fences, deploys the HTML


### Update an existing deployment

Keep the same URL while the LLM iterates:

```bash
uptool deploy v2.html --update x7k2mq
# same URL, new content

List deployments

uptool list
# x7k2mq  http://x7k2mq.mydev.com  [dashboard.html]  expires in 71h 45m

Remove a deployment

uptool rm x7k2mq

Daemon control

uptool stop      # stop the daemon
uptool status    # check if running + last 10 log lines

LLM integration

Tell your LLM to deploy files using uptool deploy. Example prompt addition:

When you create an HTML file for me to review, run uptool deploy <filename> and include the returned URL in your response.

Works with Claude Code, Cursor, Cline, or any tool-enabled LLM that can run shell commands.


How it works

uptool serve
  ├── Public server  (port 3000)  — routes by subdomain slug → serves HTML
  └── Internal API   (port 3001)  — localhost only, accepts deploy/list/rm

uptool deploy file.html
  └── POSTs HTML to internal API → gets slug back → prints URL

Files stored at ~/.uptool/files/<slug>.html. Manifest at ~/.uptool/files/manifest.json. Expired files cleaned on startup and hourly.


TTL format

| Value | Meaning | |-------|---------| | 72h | 72 hours | | 7d | 7 days | | 30m | 30 minutes | | 0 | Never expires |


Security & threat model

uptool serves files from your machine on your domain, reachable by anyone on the internet. Understand what that means before you point a domain at it.

  • Anything you deploy is public. There is no login wall on served pages. Anyone with the URL can view the content. Don't deploy secrets, credentials, or private data.
  • Slugs are unguessable; names are not. Random slugs (x7k2mq) are 8 chars of crypto-random base36 — not enumerable. But a named deployment (--name dashboard) is trivially guessable (dashboard.yourdomain). Use names only for content you're fine exposing.
  • You are responsible for what you host. Serving content on your domain makes you the publisher of it. Don't deploy untrusted HTML you wouldn't stand behind.
  • The internal API is loopback-only and Host-checked. It binds to 127.0.0.1 and rejects any request whose Host isn't a loopback name, which blocks DNS-rebinding attacks from the browser. It has no auth token — on a multi-user machine, any local user can reach it, so don't run the daemon on a shared host you don't trust.
  • Use HTTPS for anything real. Set cert_file/key_file (certs for your own domain), or terminate TLS at a proxy such as Cloudflare Tunnel. Plain HTTP sends content — and the live-reload socket — in the clear.
  • Abuse controls. The public server sets request/header/idle timeouts by default. For raw internet exposure you can also set rate_limit_rpm. Behind a proxy/tunnel, set trust_proxy = true so the limit keys off the real visitor IP instead of the proxy.

Found a vulnerability? Open an issue at https://github.com/pyeom/uptool/issues (or mark it security-sensitive).


License

MIT — see LICENSE.