luhui1hao/SuperDownloader

★ 0Forks 0RustGitHub ↗Compare

README

SuperDownloader

SuperDownloader is a desktop media downloader built with Tauri, React, TypeScript, Rust, and yt-dlp. Windows and macOS installers bundle yt-dlp, so end users can download media immediately after installation.

Instagram image posts are supported alongside videos. For carousel posts, the app follows the img_index in a shared URL and offers both Download current image and Download all images. Each carousel image is saved as an independent task with a unique numbered filename.

Douyin image notes are supported through both short share links and canonical /note/ URLs. They use the same current-image and all-images workflow while reusing the app's anonymous Douyin session handling.

Requirements

  • Windows 10 or later
  • Node.js and npm
  • Rust with the x86_64-pc-windows-msvc toolchain
  • PowerShell 5.1 or later

Development

npm install
npm run prepare:sidecars
npm run tauri dev

The sidecar preparation script downloads fixed releases of yt-dlp, Deno, and FFmpeg, then validates both archives and extracted files with SHA256. Downloads are cached under .cache/sidecars and executable files remain ignored by Git.

Use npm run verify:sidecars to validate an existing checkout without network access.

Build

npm run tauri build

Tauri runs prepare:sidecars before development and production builds, so a clean checkout can produce the same sidecar set described by src-tauri/sidecars/manifest.json.

The trusted Instagram and Douyin image extractor extensions under src-tauri/yt-dlp-plugins are also bundled as application resources. They add original-image formats to yt-dlp without requiring Python, gallery-dl, or a separate user installation.

Release packages

Windows release packages include the verified yt-dlp.exe sidecar:

npm run package:windows

Use npm run package:windows -- -Bundles msi or npm run package:windows -- -Bundles both to choose the installer format. Output is written below src-tauri/target/release/bundle. These release scripts skip updater artifacts, so an update signing key is not required for a normal installable package.

On macOS, the package script downloads the pinned official universal yt-dlp binary, verifies it against the release checksum list, and includes it in both the .app and .dmg outputs. Homebrew is not needed on an end user's Mac.

npm run package:mac

The first macOS build still needs the native Tauri/Xcode prerequisites. Run npm run bootstrap:mac to install the development dependencies.

To create a universal macOS build on a Mac with both Rust targets installed:

TAURI_TARGET=universal-apple-darwin npm run package:mac

Windows Releases And App Updates

Windows updates are published through GitHub Releases. Pushing a stable version tag starts .github/workflows/release-windows.yml, which validates every project version, builds a signed NSIS package, and publishes the installer, updater signature, and latest.json.

The application checks this endpoint when the user selects Check for updates in Settings:

https://github.com/luhui1hao/SuperDownloader/releases/latest/download/latest.json

One-time signing setup

The production private key and password are stored locally as ignored files:

.cache/super-downloader-updater.key
.cache/super-downloader-updater.password

After authenticating GitHub CLI, copy them into encrypted repository secrets:

gh auth login
Get-Content -LiteralPath ".cache/super-downloader-updater.key" -Raw |
  gh secret set TAURI_SIGNING_PRIVATE_KEY --repo luhui1hao/SuperDownloader
Get-Content -LiteralPath ".cache/super-downloader-updater.password" -Raw |
  gh secret set TAURI_SIGNING_PRIVATE_KEY_PASSWORD --repo luhui1hao/SuperDownloader

Back up both local files in a secure password manager or encrypted archive. GitHub does not allow reading a secret back after upload. Losing either value prevents publishing updates accepted by existing installations.

Publish a version

Use a stable semantic version without a leading v. The preparation command updates package.json, package-lock.json, src-tauri/Cargo.toml, src-tauri/Cargo.lock, and src-tauri/tauri.conf.json together:

npm run release:prepare -- 0.2.3
npm run test:release
npm test
npm run build
git add package.json package-lock.json src-tauri/Cargo.toml src-tauri/Cargo.lock src-tauri/tauri.conf.json
git commit -m "chore: release v0.2.3"
git push origin master
git tag v0.2.3
git push origin v0.2.3

The tag must match all project versions or the workflow stops before building. After the workflow succeeds, verify that the GitHub Release includes latest.json, an NSIS setup executable, and its .sig signature. Draft and prerelease entries do not become the application's latest update.

Local signed build

To confirm the production signing identity before publishing:

$env:TAURI_SIGNING_PRIVATE_KEY=(Get-Content -LiteralPath ".cache/super-downloader-updater.key" -Raw)
$env:TAURI_SIGNING_PRIVATE_KEY_PASSWORD=(Get-Content -LiteralPath ".cache/super-downloader-updater.password" -Raw)
npm run tauri build -- --bundles nsis

Do not rotate the updater key as a normal release. Existing installations trust the public key embedded in their installed application. Key rotation requires a bridge release signed by the old key that embeds the new public key, followed by later releases signed with the new private key.

Verification

npm run build
npm run verify:sidecars
cargo test --manifest-path src-tauri/Cargo.toml
cargo clippy --manifest-path src-tauri/Cargo.toml --all-targets --all-features -- -D warnings

Third-party license texts bundled with the application are stored in src-tauri/sidecars.

Contributors

luhui1hao

Issues