All projects/projects/fetchdeck

Fetchdeck

Ongoing

Desktop download manager built from scratch: parallel segments, pause/resume, work stealing and crash recovery.

Fetchdeck cover

About this project

Fetchdeck is a desktop download manager in the spirit of IDM. I wrote the download engine from scratch in Node, with no download libraries, to learn networking and concurrency properly, and wrapped it in an Electron + React app.

What it does

  • Segmented parallel downloads. A file is split into up to 8 byte ranges, each fetched over its own connection and written at its own offset into one pre-sized .part file. On servers that cap per-connection speed, 4 segments ran about 4x faster than 1 in my tests.
  • Pause, resume and retry. On resume the original link is re-probed, and an ETag / size check restarts the download if the file changed on the server. Expired signed links (like GitHub release URLs) are re-resolved automatically.
  • Work stealing. When one segment finishes, the engine splits the slowest remaining range in half so every connection stays busy until the end.
  • Queue. Up to 3 downloads run at once, and the rest wait in line.
  • Crash recovery. Progress is saved to disk with the file data flushed first, so killing the app mid-download loses nothing. A test kills the process with SIGKILL, resumes, and checks the SHA-256 matches the original.
  • Failure handling. Retries depend on the cause: network drops retry with capped backoff, 5xx/429 retry up to 5 times honoring Retry-After, and permanent errors fail fast. A waiting status shows when the network is down, and servers that ignore ranges fall back to a single stream.
  • Safe filenames. Server-supplied names are sanitized, so a name like ../../evil.exe can't escape the download folder.

How it's built

Four pieces with one-way dependencies: renderer → main → queue → engine.

  • engine/: plain Node library (probe, planner, segment workers, retry policy), also usable from a CLI (dl <url>)
  • queue/: download list, concurrency limit, on-disk state
  • app/main: Electron main process, wired to the UI over IPC
  • app/renderer: React UI with no download logic and no Node access, talking through a narrow contextBridge preload

Tested with Vitest against a fake server that can misbehave on demand (ignore ranges, drop connections, redirect, expire links, send extra bytes, change the file mid-download), with CI on Windows and Linux.

Design

A dark, monitor-style UI. Its signature element is the segment map: the file drawn as its byte ranges at true position and width, filled to what has arrived, with split ranges marked.

Tech used

ReactJSNode.jsTypescriptGitFigmaGitHub

Let's talk

Have a project in mind or just want to say hi? I'd love to hear from you.

© 2026 Tejas Wasnik.