dua-cli: a parallel disk usage analyzer with an interactive delete mode
View disk space usage and delete unwanted data, fast.
At a glance
- What is it?
- dua-cli is a Rust terminal tool that walks directories in parallel to report disk usage, and its interactive mode adds a multi-stage delete flow. Here is how it installs, what the pattern file does, and where ncdu or dust fit better.
- Who is it for?
- Adopt dua-cli if you want a fast aggregate listing you can pipe into scripts and an interactive mode that gates deletion behind several confirmation steps; the README describes that multi-stage process as deliberate.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What dua-cli solves, and who ends up using it
The README opens by calling dua a tool "to conveniently learn about the usage of disk space of a given directory", and the two halves of that sentence matter. The first half is measurement: dua walks a directory tree and reports how much space each entry consumes. The second half is action: the interactive mode exists so you can delete what you find without leaving the terminal.
The intended user is someone who already reaches for du and finds it slow or awkward on large trees. dua is parallel by default, and the README states it "will max out your SSD, providing relevant information as fast as possible". That is a claim about traversal strategy rather than a measured benchmark, and the repository ships a Makefile target named benchmark that runs hyperfine against the release binary, so the project expects you to check the claim on your own hardware rather than take it on faith.
The second user is the one who wants to delete. The README is explicit that "great care has been taken to prevent accidental deletions due to a multi-stage process, which makes this mode viable for exploration". That framing tells you the author considers exploratory deletion the risky part of the job, and the design answers it with friction rather than speed.
How the traversal and the two output modes work
The repository is a Cargo workspace. The root package is dua-cli at version 2.45.0, and it depends on a separate crate, dua-core, declared as a path dependency on crates/dua-lib with version ^4.0.0. That split is visible in the release list too: dua-core v4.1.0 and v4.0.0 were tagged alongside v2.45.0. The practical consequence is that the scanning engine versions independently of the command line front end, so a bug in traversal accounting is fixed in dua-core and pulled in by a version bump rather than by rewriting the binary.
On the front end, the default feature set is tui-crossplatform plus trash-move. The first pulls in crossterm, tui, unicode-width and a signal hook; the second pulls in the trash crate. If you build with --no-default-features you get a binary without the terminal interface, which the README describes as "most compatible", and there is an intermediate build, --no-default-features --features tui-crossplatform, for platforms where the trash integration is the problem rather than the UI.
Output has two shapes. By default aggregate prints a flat listing. Passing --depth N switches to an indented tree that descends N levels, and the README notes that the inputs form the first level, so --depth 1 lists exactly the entries the flat listing shows. --no-sort and --no-total behave the same in both shapes, which means you can suppress the total line in a tree report as easily as in a flat one.
Installing dua-cli and running a first aggregate
The README lists many routes. On macOS, Homebrew and MacPorts are both covered, and there is a curl-based installer script. On Linux the README is specific: the target must be named explicitly to get the MUSL build, because the installer otherwise picks a glibc-linked binary. Distribution packages exist for VoidLinux, Fedora, Arch, NixOS and NetBSD. On Windows, Scoop and WinGet are both documented, and a pre-built binary from the releases page is the fallback.
If you prefer to build it, cargo is the route the README shows, and it notes that Windows currently needs nightly features:
cargo install dua-cliOnce installed, running the bare command counts the current working directory, and passing a glob counts the matching directories. The README gives exactly these two examples:
# count the space used in the current working directory
dua
# count the space used in all directories that are not hidden
dua *For anything beyond that, the README points at subcommand help rather than documenting every flag inline:
dua aggregate --helpA first real use is a tree report you can paste into a ticket. The README's own example shows each top-level entry plus one level below it:
dua aggregate --depth 2The ignore file, and why it is the most interesting flag
--ignore-from FILE reads gitignore-style patterns and leaves everything they match out of the report, in aggregate and interactive mode alike. The README frames the use case precisely: it is the --exclude-from of rsync and the --exclude-file of restic, so the same file can answer "how much of this would actually get backed up?". That is a sharper question than "how big is this directory", and it is the one that usually matters when a backup window is too short.
The syntax is .gitignore syntax: # comments, a trailing slash to match directories only, a leading slash to anchor to the current working directory or the traversal root, ** to span directories, and ! to re-include something an earlier pattern excluded. Matching is case-sensitive on every platform, which is a deliberate divergence from case-insensitive filesystems and worth knowing before you write a pattern for a directory named Build on macOS.
The README gives a worked example:
cat .duaignore
# /target/
# **/node_modules/
# *.log
# !important.log
dua --ignore-from .duaignoreTwo constraints are stated plainly. First, the option can be given more than once, and later files win over earlier ones, so layering a global ignore file under a project-specific one is supported. Second, excluded directories are not descended into at all, so their contents cannot be re-included. The README calls this "the same restriction Git has", and it is a real limitation: if you exclude node_modules at the top and then try to re-include one package inside it, the pattern will not fire, because dua never looked inside. The option can also be set through the DUA_IGNORE_FROM environment variable.
Interactive mode, deletion, and the APFS clone caveat
Interactive mode is launched with the i or interactive subcommand, and ? brings up the keyboard help. Pressing ] minimizes or restores the entire right side of the interface, and Tab cycles through visible panes; when the right side is minimized, ? restores and focuses Help. The README presents the interface as localized through the standard POSIX variables in the usual precedence order, LC_ALL over LC_MESSAGES over LANG, with English as the default and translations for German, Japanese, Korean and Simplified Chinese, available when the locale uses UTF-8 or omits the codeset.
Deletion is where the design gets opinionated. The README describes a multi-stage process intended to prevent accidental deletions, and that is a deliberate trade: more keystrokes per deletion in exchange for a mode you can safely browse in. If you want one-keystroke destructive behavior, this is the wrong tool, and that is a design choice rather than a gap.
The macOS-specific flag deserves attention. --deduplicate-apfs-clones counts fully shared APFS file clones only once in aggregate and interactive runs. It is opt-in, and the README gives the reason: collecting the additional metadata reduces traversal performance. Two boundaries are stated. Files that share only some blocks are not deduplicated, so partial clones still count at full size. And --apparent-size still reports each file's logical length regardless, so the two flags answer different questions and should not be expected to agree. On a volume with heavy clone usage, the number you get without the flag can be substantially larger than the space actually consumed, and the flag costs you traversal time to correct it.
dua-cli against ncdu, dust and plain du
The honest comparison is not feature parity, because these tools disagree about what the primary output should be.
ncdu is the closest in spirit: a terminal disk usage browser. The difference is in the traversal model. dua is parallel by default and the README leans on that as the reason to switch; ncdu's model is not described in the README of this project, so the fair statement is that dua's parallelism is the property the project itself advertises, and you should measure it on your own tree rather than assume a multiple.
dust is a different shape of tool. It prints a tree with bars and exits; there is no interactive delete mode to speak of, and the README of this project does not discuss it. If your workflow is "look at the output, then decide", dust fits. If your workflow is "look, then delete without leaving the terminal", dua's interactive mode is the part dust does not have.
Plain du is the baseline dua is competing with, and the README's own framing is that dua deletes "more quickly than rm" as well as measuring faster. That second claim is about the delete path, not the scan, and it is the kind of claim you should verify against your own filesystem before trusting it on production data.
The gap in this comparison is machine-readable output. The README documents flat listings and --depth trees, and does not document a JSON or similar structured export. If you need to feed usage data into a dashboard, none of the documented flags get you there, and you would be parsing text.
Licence, maintenance and the cost of upgrading
dua-cli is MIT licensed, and the workspace manifest sets license.workspace = true so the root package and dua-core share the same identifier. MIT is permissive: it permits commercial use and modification, and it requires that the copyright notice and permission notice be preserved in copies. That is a summary of the identifier, not legal advice; if you vendor the code or ship a modified binary, have someone check the notice requirements against your distribution channel.
The last push to the repository was on 2026-09-12, and v2.45.0 was tagged the same day, with dua-core v4.1.0 and v4.0.0 released on 2026-09-12 and 2026-09-07 respectively. The repository is not archived.
Upgrade cost is where the workspace split pays off and where it can bite. Because dua-cli depends on dua-core with a caret range, ^4.0.0, a 4.x bump of the core crate can be pulled in without a dua-cli release. That is convenient until a traversal accounting change alters a number you were tracking. The release list shows dua-core going from 4.0.0 to 4.1.0 in five days, which is a reminder that the engine moves on its own schedule. If you depend on the reported sizes staying stable, pin the dua-core version rather than relying on the caret range.
The repository ships a Makefile with a tests target that runs check, unit-tests and journey-tests, where journey-tests executes tests/stateless-journey.sh against the debug binary. There is also a check target that runs cargo check across the default, all-features, no-default-features and tui-crossplatform-only configurations. That is a useful signal about which feature combinations the maintainer actually builds, and it means a build of your own with an odd feature set may be less exercised than the ones in that list.
Editorial conclusion
Adopt dua-cli if you want a fast aggregate listing you can pipe into scripts and an interactive mode that gates deletion behind several confirmation steps; the README describes that multi-stage process as deliberate. Skip it if you need a stable machine-readable output format, since the README documents tree and flat text output but no JSON flag, or if you are on a filesystem where APFS clone accounting matters and you cannot accept the traversal cost of --deduplicate-apfs-clones. Before rolling it out on shared storage, verify two things yourself: that your ignore patterns behave the way the README describes for anchored patterns and re-inclusion, and that the trash feature on your platform moves files where you expect rather than deleting them outright.
Frequently asked questions
How do I install dua-cli?
The README lists Homebrew and MacPorts on macOS, a curl installer script, distribution packages for VoidLinux, Fedora, Arch, NixOS and NetBSD, Scoop and WinGet on Windows, and cargo install dua-cli for building from source. On Linux the README notes the target must be specified explicitly to obtain the MUSL build.
How do I delete files with dua-cli?
Deletion happens in interactive mode, launched with dua i or dua interactive. The README states that great care has been taken to prevent accidental deletions through a multi-stage process, so expect several confirmation steps rather than a single keystroke.
How does dua-cli compare with ncdu?
Both are terminal disk usage browsers, but dua is parallel by default, which the README presents as the reason to use it for fast traversal of large trees. The README of this project does not describe ncdu's traversal model, so the parallelism claim should be measured on your own directory tree.
Does dua-cli work on macOS with APFS clones?
Yes, with an opt-in flag. --deduplicate-apfs-clones counts fully shared APFS file clones only once in aggregate and interactive runs, but the README notes it is opt-in because collecting the extra metadata reduces traversal performance, and files sharing only some blocks are not deduplicated.
Can dua-cli exclude directories from its report?
--ignore-from FILE reads gitignore-style patterns and leaves matches out of both aggregate and interactive output, and DUA_IGNORE_FROM sets the same option. Excluded directories are not descended into at all, so their contents cannot be re-included later, which the README compares to the same restriction Git has.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/byron-dua-cli)