#downloader #archive #hashing #substack

app robustack-dl

Robust Rust SubStack Downloader; Own Your Reading. Byte by Byte.

1 stable release

Uses new Rust 2024

1.1.0 Feb 16, 2026
1.0.0 Feb 15, 2026

#93 in HTTP client

GPL-3.0-only

125KB
2K SLoC

RoBustack-DL

"Own Your Reading. Byte by Byte."

License: GPL-3.0 CI Crates.io Snyk Security SLSA 3 Rust

RoBuStack-DL is a tool for digital repair, cybersecurity awareness, and resilience against mis/dis/malinformation. It allows you to archive and audit web content with integrity.


Installation

Universal (via Cargo)

If you have Rust installed, you can install the latest release directly from Crates.io:

cargo install robustack-dl

Pre-built Binaries (Linux)

Download the latest binary from the Releases page.

chmod +x robustack-dl
sudo mv robustack-dl /usr/local/bin/

From Source

Prerequisites: Rust 1.85+

Linux (Debian/Ubuntu)

# Install build dependencies
sudo apt-get update && sudo apt-get install -y build-essential pkg-config libssl-dev

# Install via cargo
cargo install robustack-dl

# OR build from source
git clone https://github.com/code-bush/robustack-dl.git
cd robustack-dl
cargo build --release

macOS

# Install OpenSSL (if not already present)
brew install openssl

# Install via cargo
cargo install robustack-dl

Windows

Ensure you have the Visual Studio C++ Build Tools installed.

# Install via cargo
cargo install robustack-dl

Usage

Version

robustack-dl -V
RoBustack-DL v1.1.0
"Own Your Reading. Byte by Byte."
[GPLv3 + Commercial License]

List posts

# List the last 10 posts
robustack-dl list --url https://example.substack.com --limit 10

List flags

Flag Short Description Default
--url <URL> -u Substack URL to list required
--limit <N> Max number of posts to list all

Download content

# Basic download (HTML format, current directory)
robustack-dl download --url https://example.substack.com

# Download as Markdown with images
robustack-dl download \
  --url https://example.substack.com \
  --output ./archive \
  --format md \
  --download-images \
  --image-quality high

# Full-featured download with all options
robustack-dl \
  --verbose \
  --rate 5 \
  --after 2024-01-01 \
  --before 2025-12-31 \
  --cookie-name substack.sid \
  --cookie-val "$SUBSTACK_TOKEN" \
  download \
    --url https://example.substack.com \
    --output ./archive \
    --format md \
    --download-images \
    --download-files \
    --file-extensions "pdf,epub" \
    --add-source-url \
    --create-archive

# Dry run — preview what would be downloaded
robustack-dl download --url https://example.substack.com --dry-run

Download flags

Flag Short Description Default
--url <URL> -u Substack URL to download required
--output <DIR> -o Output directory .
--format <FMT> -f Output format: html, md, txt html
--dry-run -n Preview mode — no files written false
--download-images Download images locally false
--images-dir <DIR> Image subdirectory name images
--image-quality <Q> Image quality: high, medium, low high
--download-files Download file attachments locally false
--files-dir <DIR> Attachment subdirectory name files
--file-extensions <LIST> Comma-separated extension allowlist (all)
--add-source-url Append source URL to each file false
--create-archive Generate an archive index page false
--limit <N> Max number of posts to download all

Audit archive integrity

robustack-dl audit --manifest ./archive/manifest.json

The audit command verifies every file in the archive against its SHA-256 hash in the manifest. Reports:

  • ✅ Files that match their expected hash
  • ❌ Hash mismatches (possible corruption)
  • ⚠️ Missing files
Flag Short Description Default
--manifest <PATH> -m Path to manifest.json manifest.json

Generate shell completions

# Bash
robustack-dl completions --shell bash > ~/.local/share/bash-completion/completions/robustack-dl

# Zsh
robustack-dl completions --shell zsh > ~/.zfunc/_robustack-dl

# Fish
robustack-dl completions --shell fish > ~/.config/fish/completions/robustack-dl.fish

Global flags

Flag Short Description Default
--verbose -v Enable debug-level logging false
--proxy <URL> -x HTTP/SOCKS5 proxy URL none
--rate <N> -r Max requests per second 2
--limit <N> Global limit on posts processed all
--after <DATE> Only process posts after this date none
--before <DATE> Only process posts before this date none
--cookie-name <NAME> Cookie name for Substack auth none
--cookie-val <VALUE> Cookie value (use env var ROBUSTACK_COOKIE_VAL) none
--config <PATH> -c Path to config.toml override none
--version -V Print version banner
--help -h Print help

Security tip: Use the ROBUSTACK_COOKIE_VAL environment variable instead of passing the cookie value on the command line, to avoid leaking it in shell history.

Logging

RoBustack-DL uses structured logging via tracing. Control verbosity with --verbose or RUST_LOG:

# Via flag
robustack-dl --verbose download --url https://example.com

# Via environment variable (fine-grained control)
RUST_LOG=debug robustack-dl download --url https://example.com

Architecture

RoBustack-DL follows clean architecture with unidirectional dependency flow:

Presentation (CLI)  →  Application (Handlers)  →  Domain (Integrity, Processor)
                                                        ↑
                                            Infrastructure (HttpClient)
Layer Modules Responsibility
Presentation cli/ Argument parsing via clap — no business logic
Application handlers/, config/ Orchestration; receives AppConfig + &dyn HttpClient
Domain integrity/, processor/ Pure business logic: hashing, manifests, content transforms
Infrastructure client/ HttpClient trait + ReqwestClient impl (swappable)

Idempotency

Every download is idempotent: content is SHA-256 hashed, stored under content-addressed filenames, and tracked in manifest.json. Re-running the same command produces zero new I/O.


Testing

# Run all tests (unit + integration + non-functional)
cargo test

# Run only unit tests
cargo test --lib

# Run only integration tests
cargo test --test cli_integration

# Run non-functional tests (performance, binary size, provenance)
cargo test --test nonfunctional

# Run with verbose output
cargo test -- --nocapture

Test categories

Suite Count What it covers
Unit tests 63 CLI parsing, AppConfig, HttpClient, Manifest, Processor
Integration tests 30 End-to-end binary: flags, exit codes, error messages
Non-functional tests 8 Startup time, binary size, provenance headers, no unsafe/println

Mission

We believe in Digital Repair. Just as we repair physical objects, we must also curate and repair our digital environments. RoBustack-DL empowers users to own their reading data, verify its integrity, and preserve it against decay or censorship.


Contributing

See CONTRIBUTING.md for development setup, pre-commit hooks, Jira commit conventions (DSO- prefix), and coding standards.

Security

See SECURITY.md for our vulnerability disclosure policy.

License

Dual-Licensed: GPLv3 + Commercial. See LICENSE for details.

Dependencies

~23–34MB
~517K SLoC