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

@pathcosmos/dleft

v0.1.7

Published

ASCII disk usage (physical disks, partitions, filesystems) for macOS and Linux.

Readme

dleft

CI npm Node License: MIT Platform

ASCII disk usage for macOS and Linux — physical disks, partitions, and mounted filesystems, rendered as dense tables with usage bars. Read-only: never mutates disk state.

$ dleft
PHYSICAL DISKS
ID      MODEL              SIZE (TiB)  USED (TiB)  FREE (GiB)  USE%  BAR
disk3   APPLE SSD AP1024N         0.9         0.4       507.6   45%  █████▓▓▓▓▓▓
disk13  External 2TB              1.8         1.0       790.0   58%  ██████▓▓▓▓▓

FILESYSTEMS
MOUNT             DEVICE          FSTYPE  SIZE (GiB)  USED (GiB)  FREE (GiB)  USE%  BAR
/mnt/data         /dev/sdb1       ext4        1863.0       931.3       931.3   50%  █████▓▓▓▓▓
/home             /dev/mapper/…   ext4         367.8       191.9       175.9   52%  █████▓▓▓▓▓
/                 /dev/mapper/…   ext4          98.0        33.0        67.0   33%  ███▓▓▓▓▓▓▓

Cells turn yellow at ≥75 % use and red at ≥90 %.

Quick start

From source (current path until v0.1.0 hits npm)

git clone https://github.com/pathcosmos/cli-ascii-usage
cd cli-ascii-usage
npm install
npm run build
node dist/cli.js              # run once
npm link                      # optional: expose `dleft` globally

From npm

npm install -g @pathcosmos/dleft
# or one-shot:
npx @pathcosmos/dleft

The bin name is dleft (so the global install gives you dleft, not pathcosmos-dleft). Requires Node.js ≥ 22. Single-file ESM bundle, no postinstall hooks.

Usage

dleft [options]

| Flag | Description | Default | |---|---|---| | -j, --json | Emit JSON (schemaVersion: 1); suppresses color. | off | | -a, --all | Include pseudo-filesystems (tmpfs, overlay, etc.). | off | | -s, --sort <field> | Sort by size / used / free / use% / name. | size | | --si | SI units (KB, GB, TB) instead of IEC (KiB, GiB, TiB). | IEC | | --no-bars | Hide the bar column. | bars on | | --no-color | Disable ANSI color. Respects NO_COLOR env. | auto | | --only <section> | Render only disks or fs. | both | | -h, --help | Show help. | — | | -V, --version | Print version. | — |

Recipes

dleft --sort use%             # which mounts are full?
dleft -a                      # show tmpfs, overlay, etc.
dleft --only disks            # just the physical-disk summary
dleft --no-color > usage.txt  # capture for diff later
dleft --json | jq '.filesystems[] | select(.usedBytes / .sizeBytes > 0.9) | .mountpoint'

Environment

  • NO_COLOR=1 — disables color (standard).
  • DLEFT_ASCII=1 — forces ASCII bar chars (#, -) instead of unicode blocks.

Exit codes

| Code | Meaning | |---|---| | 0 | Success (may still emit warnings to stderr). | | 1 | Fatal: unsupported platform, missing required command, parse failure. | | 2 | Invalid argument. |

How it works

                ┌──────────────────────┐
                │   src/cli.ts         │  parseArgs → RenderOptions
                └────────────┬─────────┘
                             │
        ┌────────────────────┴────────────────────┐
        ▼                                         ▼
┌──────────────────┐                    ┌──────────────────┐
│ collectors/      │                    │ render/          │
│  ├ darwin.ts     │  diskutil + df     │  ├ disks.ts      │
│  ├ linux.ts      │  lsblk   + df      │  ├ filesystems.ts│
│  └ index.ts      │                    │  ├ bar / unit /  │
└────────┬─────────┘                    │  │  color / width│
         │ DiskReport                   │  └ index.ts      │
         └─────────────────►─────────────►  pure(): string │
                                        └──────────────────┘
  • Collectors spawn subprocesses through a CommandRunner interface (DI seam) and parse output into a DiskReport. The production runner uses Node's execFile with a fixed argv array — no shell, no injection surface — and a 5-second timeout. Tests use a FakeRunner seeded from committed fixtures.
  • Render is a pure function: render(report, opts) → string. No stdout, no env, no TTY checks. All environmental decisions (color, width, unicode) happen in cli.ts and are passed in.
  • A timeout on one data source emits a warning and the others still render (partial success → exit 0).

Platform notes

| Platform | Required commands | |---|---| | macOS | diskutil, df | | Linux | lsblk, df |

macOS: APFS containers

One physical-disk row per APFS container. Used bytes come from container-level CapacityCeiling - CapacityFree, not Σ per-volume CapacityInUse — summing volume usage double-counts shared space across APFS volumes in the same container. If diskutil apfs list times out, the disk summary is omitted with a warning rather than inferred from df (silently wrong numbers in a disk-space tool are worse than fewer numbers).

Linux: LVM, LUKS, overlay

Filesystems are joined to physical disks by walking the lsblk tree. LVM volumes and LUKS-backed partitions map to their parent block device. Bind mounts and overlay filesystems are flagged as pseudo and hidden by default (--all to show).

JSON output

dleft --json

Emits a DiskReport document. The shape is stable under schemaVersion: 1; gate downstream consumers on that field:

dleft --json | jq 'if .schemaVersion == 1 then .filesystems else error("unexpected dleft schema") end'

schemaVersion will only bump on a breaking change to the report shape — non-breaking additions keep 1.

Why not just df?

  • df doesn't show physical-disk totals or APFS container reconciliation.
  • df output alignment breaks on long device paths (/dev/mapper/…).
  • df doesn't know about bind mounts, pseudo-filesystems, or LVM parent disks.
  • dleft isn't a replacement — it's a denser skim for "where is my space?"

Development

npm install
npm test           # Vitest: unit + collectors + CLI + smoke (~1.4 s)
npm run typecheck  # tsc --noEmit
npm run build      # tsup → dist/cli.js (12 KB ESM bundle, shebang)
node dist/cli.js   # run the built bundle

Fixtures live under tests/fixtures/{darwin,linux}/. FakeRunner (tests/helpers/fake-runner.ts) injects fixture strings so collector tests run the real parser without spawning subprocesses. Refresh fixtures via the snippets in tests/fixtures/README.md.

CI matrix: Node 22 / 24 × Ubuntu / macOS. Releases publish to npm via OIDC keyless provenance on v* tag push.

License

MIT. See LICENSE.