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

cmdflare

v0.2.0

Published

Smart, complete Cloudflare API command line: every endpoint of the Cloudflare SDK as commands, with interactive (human) and non-interactive (CI) modes.

Readme

cmdflare

npm CI node license

The Cloudflare API, as a command. List DNS, purge cache, ship Workers — from a terminal or from CI. 2,500+ commands, generated from the official SDK.

$ cmdflare dns records list --zone example.com
id                                name              type  content        proxied  ttl
3f1c…                             www.example.com   A     203.0.113.10   true     1
a8b2…                             example.com       MX    mail.example   false    3600

$ cmdflare dns records create --zone example.com --type A --name api --content 203.0.113.20 --proxied --ttl 1 --json
{ "id": "…", "name": "api.example.com", "type": "A", … }

$ cmdflare workers scripts list -A "My Account" --all -q '[*].id'

Try it

npm i -g cmdflare          # Node.js ≥ 20; or: bunx cmdflare / npx cmdflare
cmdflare auth login        # paste a Cloudflare API token
cmdflare zones list

Create a token at API Tokens (user) or Manage Account → Account API Tokens (account-owned, cfat_…). Then:

cmdflare dns records list --zone example.com
cmdflare cache purge --zone example.com --purge-everything --yes

Or skip login and export CLOUDFLARE_API_TOKEN (also CLOUDFLARE_TOKEN / CF_API_TOKEN).

Interactive

Run cmdflare with no arguments. Type dns records, pick a zone by name, fill the rest. It prints the equivalent one-liner so you can paste it into a script later.

Same idea for a partial path: cmdflare dns records opens that menu. On a TTY, missing flags are prompted instead of failing — cmdflare dns records get will ask for the record and the zone.

For agents

cmdflare is not in model training data. Discover at runtime — do not scrape TTY help:

cmdflare search dns records --json
cmdflare dns records list --help --json
cmdflare dns records list --zone example.com --json --no-input

Full instructions: cmdflare skill (also skills/cmdflare/SKILL.md, llms.txt, AGENTS.md).

Commands

cmdflare <resource> [<subresource>...] <command> [arguments] [flags]

Resources match the API: zones, dns records, workers scripts, kv namespaces values, r2 buckets, zero-trust access applications, rulesets, … Commands are SDK methods (list, get, create, update, edit, delete, plus purge, verify, rotate, …). kebab-case and camelCase both work; ls / rm / show / add are aliases.

cmdflare --help
cmdflare dns --help
cmdflare dns records create --help
cmdflare search purge cache
cmdflare help --tree zero-trust

Path ids are positional (cmdflare dns records get <dns-record-id>). Everything else is a --flag named after the API field. Zones and accounts accept names: --zone example.com, -A "Acme Corp" (or CLOUDFLARE_ZONE_ID / CLOUDFLARE_ACCOUNT_ID, or a profile default).

Bulk export

A few commands are whole workflows rather than one API call.

cmdflare stream export ./backup              # every Stream video + a CSV manifest
cmdflare stream export ./backup --compress   # …and ./backup.tar.gz
cmdflare stream export ./backup --dry-run    # what it would download, without touching anything
cmdflare stream export ./backup --retry-failed   # re-attempt only what failed last time

stream export walks the whole library, saves each video as <id>.mp4 and each caption track as <id>.<language>.vtt, and writes videos.csv with every video's id, title, description, public URLs, flags, dates, captions, the full custom meta object and the relative path to each file. Existing files are skipped, so an interrupted export resumes. Every MP4 render is requested up front (--request-concurrency, default 16) so Cloudflare renders the library in parallel, then files are downloaded as they become ready (--concurrency, default 4) — a big library takes about as long as one render, not one per batch. The generated MP4s are kept on your account (they count towards Stream storage; remove them with cmdflare stream downloads delete <id>). Use --metadata-only for the CSV alone, --limit / --creator / --search / --start / --end to export a subset.

If a run ends with failures (exit 1, an error column in the CSV), --retry-failed reads the manifest and re-attempts only those videos — no re-listing, no other rows touched — then updates their rows in place.

Scripts and CI

JSON when piped, tables on a TTY. Destructive commands ask on a TTY and need --yes otherwise. --no-input (or CI=true) never prompts.

- run: bunx cmdflare cache purge --zone example.com --purge-everything --yes
  env:
    CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }}

Exit codes: 0 ok · 1 API/other · 2 usage · 3 auth · 4 not found · 5 rate limited · 130 cancelled.

Output

| Flag | Effect | | --- | --- | | -o table (TTY default) | Columns picked automatically, fits the terminal | | -o json / --json (piped default) | Pretty JSON (--compact for one line) | | -o yaml, -o csv, -o tsv, -o ndjson, -o raw, -o id | … | | -q, --query <path> | Select data: [*].name, [?status==active].id | | --fields id,name,account.name | Restrict columns / keys | | --all / --limit <n> | Every page / cap items | | --dry-run / --curl | Print the request (or a curl) without sending it |

Stdout is data. Hints, spinners, and errors go to stderr.

Flags in more detail

  • Types come from the SDK: booleans (--proxied, --proxied=false), numbers, enums, arrays (--tags a,b or JSON or repeated flags), objects (--settings '{"ipv4_only":true}' or --settings.ipv4-only true), files (--value ./file.bin, @- for stdin).
  • --description @notes.txt and --data @- read a file or stdin.
  • -d/--data '{…}' (JSON or YAML) sets the whole body; --set key.path=value patches nested fields; flags win over --data.
  • If a parameter shares a name with a global flag (--data on DNS create, --limit on some lists), the parameter wins. Use -d / -q / -o or --cf-<flag> for the global. --help says which.
  • --include-meta wraps {result, result_info, has_more}. --raw-response prints the API envelope. --output-file writes downloads.

Auth and profiles

cmdflare auth login
cmdflare auth login --token "$CF_TOKEN" -p ci
cmdflare auth status
cmdflare auth whoami
cmdflare auth logout

Lookup order: --tokenCLOUDFLARE_API_TOKEN (CLOUDFLARE_TOKEN, CF_API_TOKEN) → CLOUDFLARE_API_KEY + CLOUDFLARE_EMAIL → the active profile.

User tokens (cfut_… or older unprefixed strings) and account-owned tokens (cfat_…) both go out as Authorization: Bearer. Global API keys (cfk_…) still need --api-key and --email.

Config is ~/.config/cmdflare/config.json (cmdflare config path). A profile stores the token plus optional default account/zone:

cmdflare config set account_id 8c7434c9906dab3c23d2dd5d46fbb649
cmdflare config set zone_id example.com          # names are resolved on use
cmdflare config set output yaml
cmdflare config use staging                      # or -p staging / CMDFLARE_PROFILE

Raw API

Any REST path, including endpoints the SDK does not model yet:

cmdflare api /zones -P per_page=5
cmdflare api GET '/zones/{zone_id}/dns_records' -Z example.com --paginate -q '[*].name'
cmdflare api POST '/zones/{zone_id}/purge_cache' -Z example.com -d '{"purge_everything":true}'
cmdflare api DELETE /zones/<id>/dns_records/<rid> --yes

{account_id} / {zone_id} are filled from context. -P is query or body; -H adds headers; --paginate follows pages.

Completion

echo 'eval "$(cmdflare completion bash)"' >> ~/.bashrc
echo 'eval "$(cmdflare completion zsh)"'  >> ~/.zshrc
cmdflare completion fish > ~/.config/fish/completions/cmdflare.fish

Environment

| Variable | Meaning | | --- | --- | | CLOUDFLARE_API_TOKEN (CLOUDFLARE_TOKEN, CF_API_TOKEN) | API token | | CLOUDFLARE_API_KEY + CLOUDFLARE_EMAIL | Legacy global API key | | CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_ZONE_ID | Default account / zone (id or name) | | CLOUDFLARE_BASE_URL | API base (default https://api.cloudflare.com/client/v4) | | CMDFLARE_PROFILE | Config profile | | CMDFLARE_CONFIG_DIR, CMDFLARE_CACHE_DIR | Config / cache locations | | CMDFLARE_NO_INPUT, CI | Never prompt | | NO_COLOR, FORCE_COLOR | Color |

Development

From a clone (Bun ≥ 1.1):

bun install
bun run build            # manifest + dist/cli.js
bun link                 # `cmdflare` on your PATH
bun src/cli.ts --help    # or run TypeScript directly
bun test
bun run typecheck
bun run dev -- zones list

scripts/gen-manifest.ts walks the cloudflare package and writes src/generated/. Re-run bun run gen after upgrading the SDK — new endpoints become commands. Runtime loads only the SDK module for the command you ran.

License

GPL-3.0 — see LICENSE.