devto 2026-09-22 원문 보기 ↗
Over time, every workstation accumulates duplicate files: duplicated photo backups, repeated downloads of large zip archives, cloned repositories, and redundant ISOs. They quietly eat gigabytes of expensive SSD storage.
Most people write a simple script that reads all files and compares their hashes. But on large drives, that naive approach has two fatal problems:
fs.readFileSync) crashes the Node.js event loop with out-of-memory errors.To solve this efficiently, I built HashDup — a fast, memory-safe CLI duplicate finder built with native Node.js streams and a smart 2-phase scanning engine.
HashDup uses an algorithmic filtering pipeline that avoids unnecessary disk reads:
[All Target Files]
│
▼
Phase 1: Size-First Grouping (O(1) filter)
└── Discard all files with unique byte sizes without reading contents!
│
▼ (Only files with identical sizes remain)
Phase 2: Chunked Streaming SHA-256 Hashing
└── Streams files in 64KB buffers (Flat O(1) memory consumption)
│
▼
[Identified Duplicate Sets & Reclaimable Space]
Before reading any file content, HashDup runs a lightweight metadata scan using fs.promises.stat().
If a file has a unique size in bytes, it is physically impossible for it to be a duplicate of any other file. We discard these immediately. On a drive with 10,000 files, this eliminates 90%–95% of candidates in milliseconds!
For candidate files that share the exact same byte size, we compute cryptographic SHA-256 digests.
Instead of buffering whole files into RAM, HashDup uses Node.js streams:
import fs from 'node:fs';
import crypto from 'node:crypto';
function hashFile(filePath) {
return new Promise((resolve, reject) => {
const hash = crypto.createHash('sha256');
const stream = fs.createReadStream(filePath);
stream.on('data', chunk => hash.update(chunk));
stream.on('end', () => resolve(hash.digest('hex')));
stream.on('error', reject);
});
}
This ensures that whether a file is 2 KB or 10 GB, Node.js memory usage stays constant at around 30MB of RAM.
crypto, stream, fs/promises).You can test it right now on any directory using npx:
# Scan current directory and preview duplicates
npx hashdup-cli scan .
# Scan with custom output format or dry-run
npx hashdup-cli scan ~/Downloads --min-size 1MB
HashDup is open source under the MIT license.
🔗 GitHub Repository: github.com/mahdyarmonfared/hashdup-cli
I'd love to hear from other CLI developers:
Feedback, PRs, and ⭐ stars on GitHub are always appreciated!