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

@cliftonc/cfld

v0.2.5

Published

Zero-token, persistent Cloudflare tunnel CLI for local dev — same public HTTPS URL every run.

Readme

cfld

cfld = cloudflare local dev.

One command to give your localhost a permanent public HTTPS URL — no API tokens, no teardown.

cfld wraps cloudflared into a frictionless dev experience: the same custom URL every run (not a random trycloudflare.com one), authorized with a browser login (zero API tokens), reusing the same named tunnel and DNS record across restarts instead of churning them. It runs a live dashboard (URL, connection count, request/latency counters, tailing logs), auto-reconnects on edge blips, and guards against stealing a DNS record that belongs to another tunnel.

Getting started

New here? Just run this — it walks you through everything, no account or config needed to start:

npx @cliftonc/cfld setup

setup is the front door. It checks cloudflared for you, then lets you pick:

  1. A public URL right now — free, no account, no domain (a temporary trycloudflare.com URL). Great for a webhook, a demo, or just trying it.
  2. A persistent custom URL — opens the browser to sign in (or sign up — it's free), then wires up the same URL for every future run.

You don't even have to remember setup: the first time you run bare cfld in a fresh project, it drops you into this same guided flow so you're never stuck guessing.

Already know what you want? Skip straight to it:

# instant public URL in seconds — no account, no config
npx @cliftonc/cfld --quick 3000   # temporary trycloudflare.com URL

# the everyday command — reuse-or-create your persistent tunnel and go live
npx @cliftonc/cfld            # detect your dev port, go live on the same URL
npx @cliftonc/cfld 3000       # explicit port

# or install once and use the short `cfld` command everywhere
npm i -g @cliftonc/cfld
cfld setup

What it costs

cfld is built to get you going at zero → near-zero cost, and it's honest about the one thing it can't automate:

  • Instant URLcfld --quick: free, no account, no domain. The URL is temporary and changes each run.
  • Cloudflare accountfree. cfld opens the browser to sign in (the same page has a Sign up link); there's no API token to create. Account signup itself can't be scripted — Cloudflare requires a browser, terms acceptance, and email verification.
  • Persistent custom URL — needs a domain on Cloudflare. Free if you already own one (just add the site); otherwise a domain is a few dollars/year via Cloudflare Registrar. No account has a free permanent subdomain.

Why not just cloudflared?

The persistent-tunnel flow normally means: create an API token in the dashboard, find your zone/account IDs, tunnel create, hand-write a config.yml, route dns, and remember not to delete anything. cfld collapses all of that into one idempotent command and adds the dev niceties (auto port detection, deterministic hostname, .env write-back, a live status view).

Compared to the alternatives:

  • untun — random URLs only (quick tunnels). cfld gives you a stable one.
  • cf-tunnel — needs an API token and tears the tunnel + DNS down on exit. cfld uses browser login and preserves resources so the URL is truly persistent.
  • @agencyhandy/tunneler — global install + API token + zone id. cfld is npx-first and zero-token.

Requirements

  • Node.js ≥ 18
  • A domain on Cloudflare (nameservers pointed at Cloudflare) for a persistent custom URL. Don't have one yet? cfld guides you, and cfld --quick works immediately with an ephemeral URL.
  • cloudflared — used from your PATH if present, otherwise auto-downloaded via the optional cloudflared npm package.

How it works

Every run reconciles four things, treating Cloudflare as the source of truth and local files as a cache:

  1. Cert — per-domain cert stored at ~/.cfld/certs/<zone>.pem, obtained once via cloudflared tunnel login (browser, no token) and selected with --origincert so multiple domains coexist on one machine.
  2. Tunnel — reused by name (cfld-<slug>) if it exists, created only if absent. Never deleted on exit.
  3. DNSroute dns --overwrite-dns points <slug>.<zone> at the tunnel (idempotent).
  4. Config — a generated ingress file + your public URL written into ./.env (PUBLIC_URL by default).

A machine-wide registry at ~/.cfld/registry.json indexes every tunnel, so you can manage them from anywhere.

Commands

| Command | What it does | |---|---| | cfld --quick [port] | Instant trycloudflare.com URL — no account, no cert/domain (temporary). | | cfld setup | Guided first-run — pick the instant free URL or set up a persistent one. | | cfld [port] | Ensure + run a persistent tunnel (reuses the same URL). | | cfld login [--reauth] | Authorize with Cloudflare in your browser. --reauth adds another domain. | | cfld init | Configure a persistent tunnel without running it. | | cfld list | List all tunnels across projects/domains. | | cfld status [name] | Show details for a tunnel. | | cfld up <name> | Run a registered tunnel by name from anywhere. | | cfld destroy [name] | Delete a tunnel (explicit, opt-in). | | cfld service <action> [name] | Always-on background service: install/uninstall/start/stop/status. | | cfld doctor | Diagnose your setup. |

Options

--name <slug>     Override the project name (default: package.json name / dir)
--host <fqdn>     Explicit public hostname (e.g. api.example.com)
--zone <domain>   Cloudflare domain to use (e.g. example.com)
--env <KEY>       .env key to write the URL to (default: PUBLIC_URL)
--no-env          Don't write the URL to .env
--force           Skip confirmation (destroy)

Configuration (optional)

Everything is inferred by default, but you can commit intent to package.json under a "cfld" key. Authored values win over the machine-local .cfld.json cache (so edits take effect immediately); only the resolved tunnel UUID comes from the cache.

{
  "cfld": {
    "zone": "example.com",
    "name": "myapp",          // → myapp.example.com
    "envKey": "PUBLIC_URL"
  }
}

Multiple services from one tunnel (multi-ingress)

Expose an API and a web app at once with a routes array:

{
  "cfld": {
    "zone": "example.com",
    "routes": [
      { "name": "app", "port": 3000 },                 // app.example.com → :3000
      { "name": "api", "port": 8080, "path": "/v1" },  // api.example.com/v1 → :8080
      { "host": "hooks.example.com", "port": 4000 }    // explicit hostname
    ]
  }
}

The first route is the primary (used for the dashboard and .env). Every hostname is routed and DNS-guarded.

Always-on service

The foreground cfld is the dev default. To keep a tunnel up across logout/reboot, install it as a background service (macOS LaunchAgent / Linux systemd user unit):

cfld service install      # register + start
cfld service status
cfld service uninstall    # stop + remove (tunnel + DNS preserved)

Windows service management is not supported — run cfld in the foreground there.

Running alongside your dev server

Give cfld your dev command after a -- and it runs both as one managed unit:

cfld 3000 -- next dev

cfld will:

  • boot your dev server as a managed child, with PUBLIC_URL already in its environment (so it can read its own public URL for webhooks/OAuth callbacks — no .env round-trip needed);
  • wait for :3000 to actually listen before flipping to ● LIVE, so the URL never serves a 502 the moment you reveal it;
  • stream your dev server's logs into the same dashboard as the tunnel — one unified view;
  • stop both on a single Ctrl-C, gracefully, leaving the tunnel + DNS intact so the next run reuses the same URL;
  • exit if your dev server exits, propagating its exit code (the tunnel is still preserved).

The pass-through form (-- <cmd>) runs your command directly. If you need shell features (pipes, &&, globs), use the string form instead:

cfld 5173 --exec "npm run dev"

This works with --quick too, when you don't have a domain set up yet:

cfld --quick 3000 -- next dev

Wire it into package.json so the whole team gets the same public URL:

{
  "scripts": {
    "dev": "next dev",
    "dev:tunnel": "cfld 3000 -- next dev"
  }
}

Tip: commit a "cfld": { "zone": "example.com", "name": "myapp" } block to package.json so the URL is deterministic for the whole team — everyone's dev:tunnel maps to myapp.example.com.

cfld also works fine standalone — it only needs the port, and tolerates the app not being up yet (502 until it starts, then recovers). Run them with concurrently:

"dev:tunnel": "concurrently -k -n app,cfld -c blue,magenta \"npm:dev\" \"cfld 3000\""

or plain shell: cfld 3000 & next dev.

Development

npm install
npm run build      # tsup → dist/
npm test           # vitest unit + integration tests
npm run typecheck  # tsc --noEmit

The primary end-to-end check needs no domain or paid plan: cfld --quick against a local server, then fetch the resulting URL and assert the response round-trips through Cloudflare's edge.

License

MIT