A modern, Kotlin-first cross-platform download engine designed for maximum speed and reliability. Featuring multi-chunk parallel downloading, dynamic chunk splitting, mirror server support, token-bucket speed throttling, and WorkManager persistence.
Provides first-class, idiomatic SDKs for Android, iOS/macOS (Swift), Desktop (JVM), C# (.NET), Flutter (Dart), and React Native.
- 🚀 Dynamic Chunk Splitting: IDM-style dynamic range theft automatically shifts workload from slow streams to faster connections.
- 📂 Multi-Chunk Parallel Downloading: Splits files into multiple segments and downloads them concurrently.
- 🪞 Mirror Downloads: Round-robin mirror server assignment for concurrent downloading from alternative sources.
- 🛡️ WorkManager & Background Persistence: Survives application termination and device reboots (Android 14-16 compliant).
- 📶 Network Awareness: Auto-pauses on network loss and auto-resumes when connection is restored.
- ⏱️ Speed Throttling: Configure global or per-task download speed caps using token-bucket rate limiting.
- 🔑 Comprehensive Auth: Built-in support for Basic, Bearer, Digest, and OAuth credentials.
- 🔗 Clipboard Sniffer: Automatically checks clipboard copy operations for downloadable link patterns.
- 📦 Post-Processing Hooks: Chains operations like auto-extracting (ZIP/TAR/GZ) and hashing (MD5, SHA-256).
graph TD
App[Consumer Application] --> API[Platform SDK / Wrapper]
subgraph Wrappers [Platform Integrations]
API --> RN[React Native Wrapper]
API --> FL[Flutter Plugin]
API --> DN[.NET NuGet Package]
API --> COM[Compose / SwiftUI Components]
end
subgraph Core [KDownloader Core Engine]
RN --> CORE[kdownloader-core KMP]
FL --> CORE
DN --> CORE
COM --> CORE
CORE --> ENG[Download Engine]
CORE --> NET[HttpClientFactory]
CORE --> STO[PlatformFileStorage]
end
subgraph Storage & Network
ENG --> DB[(SQLite / Room DB)]
NET --> KTOR[Ktor Client]
STO --> OKIO[Okio File System]
end
style CORE fill:#7F52FF,stroke:#fff,stroke-width:2px,color:#fff
style ENG fill:#1976D2,stroke:#fff,stroke-width:1px,color:#fff
style DB fill:#388E3C,stroke:#fff,stroke-width:1px,color:#fff
Add the JitPack repository to your configuration:
// settings.gradle.kts or build.gradle.kts
repositories {
mavenCentral()
maven { url = uri("https://jitpack.io") }
}Then add the dependency for the core engine or platform-specific wrappers:
// build.gradle.kts
dependencies {
// Pure Kotlin Multiplatform Core
implementation("com.github.RoxyBasicNeedBot.KDownloader:kdownloader-core:v3.2.2")
// Android Library (WorkManager, Notifications)
implementation("com.github.RoxyBasicNeedBot.KDownloader:kdownloader-android:v3.2.2")
// Compose Multiplatform UI components
implementation("com.github.RoxyBasicNeedBot.KDownloader:kdownloader-compose:v3.2.2")
// Dagger Hilt Integration
implementation("com.github.RoxyBasicNeedBot.KDownloader:kdownloader-hilt:v3.2.2")
// Desktop JVM Support
implementation("com.github.RoxyBasicNeedBot.KDownloader:kdownloader-desktop:v3.2.2")
}Install the wrapper module directly from npm:
npm install kdownloader-react-nativeAdd the plugin to your pubspec.yaml:
dependencies:
kdownloader_flutter: ^2.2.0Add the package via Xcode or through your Package.swift:
dependencies:[.package(url:"https://github.com/RoxyBasicNeedBot/KDownloader.git", from:"3.2.2")]Install the C# NuGet package:
dotnet add package KDownloader.Net --version 3.2.2val downloader =KDownloader.getInstance(context)
val id = downloader.enqueue(
DownloadRequest.Builder("https://example.com/largefile.zip", "/downloads/", "file.zip")
.setPriority(DownloadPriority.HIGH)
.setChunkCount(8)
.setWifiOnly(true)
.setSpeedLimit(2_000_000) // 2 MB/s cap
.addMirrorUrl("https://mirror.example.com/file.zip")
.build()
)
// Observe download progress reactively
downloader.observe(id).collect { state ->when (state) {
isDownloadState.Downloading->println("${state.progress.percent}% at ${state.progress.speedFormatted}")
isDownloadState.Done->println("Saved to ${state.result.filePath}")
isDownloadState.Failed->println("Failed: ${state.error.message}")
else->Unit
}
}letdownloader=KDownloader.shared
letid=tryawait downloader.enqueue(DownloadRequest(
url:"https://example.com/movie.mp4",
destination:.documentsDirectory,
fileName:"movie.mp4",
chunkCount:6))
// Exhaustive Swift matching via SKIE interop
forawaitstatein downloader.observe(id){switch state {case.downloading(let progress):print("\(progress.percent)% downloaded")case.done(let result):print("Completed: \(result.filePath)")case.failed(let error, _):print("Error: \(error.localizedDescription)")default:break}}importKDownloaderfrom'kdownloader-react-native';constid=awaitKDownloader.enqueue({id: 'task-1',url: 'https://example.com/file.zip',destinationDir: '/downloads',fileName: 'file.zip',chunkCount: 4});KDownloader.observe((states)=>{consttask=states.find(s=>s.id===id);if(task&&task.status==='DOWNLOADING'){console.log(`${task.progress.percent}% | ${task.progress.speedFormatted}`);}});import'package:kdownloader_flutter/kdownloader_flutter.dart';
final downloader =KDownloaderFlutter();
final id =await downloader.enqueue(
DownloadRequest(
url:'https://example.com/file.zip',
destinationDir:'/downloads/',
fileName:'file.zip',
chunkCount:4,
)
);
downloader.observe(id).listen((state) {
if (state isDownloading) {
print('${state.progress.percent}%');
} elseif (state isDone) {
print('Downloaded: ${state.result.filePath}');
}
});This project is licensed under the BSD 3-Clause License - see the LICENSE file for details.
