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

@downloadx/cli

v0.3.0

Published

Daemon-based CLI for downloadx — parallel chunked downloads via Unix socket IPC.

Readme

@downloadx/cli

A daemon-based command-line download manager built on @downloadx/core.

downloadx keeps downloads running in the background through a small daemon that the CLI talks to over a Unix domain socket. You add a URL once, log out, log back in days later, and the download is still progressing — or already sitting in your target directory. Live progress is available via a TUI or NDJSON stream suitable for scripts and LLM/agent consumers.

Need the library itself (to embed downloads in your own app)? See @downloadx/core.

Platform: Linux and macOS only. The daemon relies on Unix domain sockets and is not supported on Windows.

Install

npm install -g @downloadx/cli

This puts the downloadx command on your PATH. The daemon is spawned automatically on the first command and shuts down with downloadx stop.

Commands

downloadx add --url <url> [--filename <name>] [--description <text>]
              [--speedLimit <n>] [--targetPath <dir>]
              [--targetChunkCount <n>] [--minChunkSize <n>] [--journal true|false]
              [--metadata.key <val>] [--headers.Key <val>]
downloadx list [--json]                               List all downloads
downloadx status  --id <#|id> [--json]                Detailed status for a download
downloadx pause   --id <#|id> | --all                 Pause one or all downloads
downloadx resume  --id <#|id> | --all                 Resume one or all downloads
downloadx restart --id <#|id> [--force] | --all       Restart from scratch, keeps list position
downloadx cancel  --id <#|id> | --all                 Cancel one or all downloads
downloadx clear   --id <#|id> [--force]               Remove from list (confirms if incomplete)
downloadx clear   --all [--force]                     Remove all (confirms incomplete ones)
downloadx clear   --completed                         Remove only completed downloads
downloadx watch [--simple|--json]                     Live progress view
downloadx stop                                        Shut down the daemon

downloadx set <key> <value> [--id <#|id>] [--override]   Set a config value
downloadx get [key] [--id <#|id>] [--json]               Get one or all config values

<#> refers to the index shown by list (e.g. 1, 2, #1, #2).

restart deletes .part files and restarts from byte zero. It always asks for confirmation unless --force is passed. The download keeps its position in the list and its original addedAt timestamp.

clear only removes the entry from the list and deletes in-progress .part, .meta, and .journal files — it never touches the finished file in the target directory.

watch --json emits one self-contained JSON event per line (progress, chunk progress, state changes, diagnostics) — a stable interface for scripts and LLM/agent consumers. status --json prints the full describe() report.

Configuration

Config is stored in ~/.local/share/downloadx/config.json and applied live without restarting the daemon.

| Key | Default | Description | | ------------------ | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | | maxParallel | 3 | Max concurrent active downloads | | speedLimit | 0 | Global speed cap shared by all downloads. 0 = unlimited. Accepts 500kb, 3mb, 1.5gb or raw bytes | | targetPath | ~/.local/share/downloadx/downloads | Default directory for completed files | | targetChunkCount | 4 | Target number of parallel chunks per download. Takes effect on the next split decision for active downloads | | minChunkSize | 1mb | Minimum chunk size before splitting stops. Accepts 500kb, 1mb, etc. Takes effect on the next split decision | | journal | true | Write an NDJSON diagnostic log (.downloadx.log) next to each download. Takes effect on the next diagnostic event |

Global keys

| Key | Default | Description | | ------------------ | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | | maxParallel | 3 | Max concurrent active downloads | | speedLimit | 0 | Global speed cap shared by all downloads. 0 = unlimited. Accepts 500kb, 3mb, 1.5gb or raw bytes | | targetPath | ~/.local/share/downloadx/downloads | Default directory for completed files | | targetChunkCount | 4 | Target number of parallel chunks per download | | minChunkSize | 1mb | Minimum chunk size before splitting stops. Accepts 500kb, 1mb, etc. | | journal | true | Write an NDJSON diagnostic log (.downloadx.log) next to each download | | headers | {} | Default HTTP headers sent with every request. Use dot-notation: set headers.Authorization "Bearer x" |

Per-download keys (set --id)

The following keys can be overridden per download. Set at add time as flags or later via set --id. Setting a key to null clears the override and reverts to the global value.

| Key | Description | | ------------------ | ----------------------------------------------------------------------------------------------------- | | speedLimit | Per-download speed cap. null = follow global | | targetPath | Override the destination directory for this download. null = follow global | | targetChunkCount | Override chunk count. null = follow global | | minChunkSize | Override minimum chunk size. null = follow global | | journal | Override journal setting. null = follow global | | filename | Override the final filename. null = use probe/URL-derived name | | description | Free-form note attached to this download. null = clear | | metadata | Arbitrary key/value data. Use dot-notation: set metadata.tag anime --id #1. null = clear all | | headers | Per-download HTTP headers merged on top of global (effective = {...global, ...local}). Use dot-notation. null = clear local overrides |

Global propagation

When you change a global key like targetChunkCount or minChunkSize, downloads that still carry the old global value pick up the new value. Downloads with a per-download override are left alone unless you pass --override, which forces the new value onto every download.

When get --id is used, the returned value is the effective value (global fallback when no override is set). Use get --id --json for machine-readable output.

JSON output

list, get, and set (when listing keys) all support --json to emit raw JSON instead of formatted text — useful for scripts and agent consumers.

downloadx set maxParallel 5
downloadx set speedLimit 3mb
downloadx set targetPath ~/Downloads
downloadx set headers.Authorization "Bearer token"     # global header
downloadx set speedLimit 1mb --id 2                    # limit only download #2
downloadx set headers.X-Custom myval --id 2            # per-download header
downloadx set speedLimit null --id 2                   # clear override → follow global
downloadx set minChunkSize 2mb --override              # force onto every download
downloadx get                                          # show all config values
downloadx get --json                                   # machine-readable
downloadx get speedLimit                               # show one value
downloadx get --id 2 --json                            # per-download effective values

The daemon's cache directory (~/.local/share/downloadx/cache) is fixed at daemon startup and is not a runtime-configurable key. In-progress .part files are stored there as {id}.part — independent of the filename — so renaming a download mid-flight never loses progress.

Development

bun install
bun run --filter @downloadx/cli test       # vitest integration suite
bun run --filter @downloadx/cli typecheck
bun run --filter @downloadx/cli build

The integration tests spin up a real daemon process per test against a temporary working directory, so they exercise the full IPC path, persistence, and command surface.

License

MIT