Electron File Download Manager
A simple and easy to use file download manager for Electron applications.
Designed in response to the many issues around electron-dl
and provides
a more robust and reliable solution for downloading files in Electron.
Use cases:
- Download files from a URL
- Get an id associated with the download to track it
- Optionally show a "Save As" dialog
- Get progress updates on the download
- Be able to cancel / pause / resume downloads
- Support multiple downloads at once
Electron 26.0.0 or later is required.
import { ElectronDownloadManager } from 'electron-dl-manager';
const manager = new ElectronDownloadManager();
const id = await manager.download({
window: browserWindowInstance,
url: 'https://example.com/file.zip',
saveDialogOptions: {
title: 'Save File',
},
callbacks: {
onDownloadStarted: async ({ id, item, webContents }) => {
},
onDownloadProgress: async (...) => {},
onDownloadCompleted: async (...) => {},
onDownloadCancelled: async (...) => {},
onDownloadInterrupted: async (...) => {},
onError: (err, data) => {},
}
});
manager.cancelDownload(id);
manager.pauseDownload(id);
manager.resumeDownload(id);
Table of contents
Installation
$ npm install electron-dl-manager
Getting started
You'll want to use electron-dl-manager
in the main process of your
Electron application where you will be handling the file downloads.
In this example, we use IPC handlers / invokers
to communicate between the main and renderer processes, but you can
use any IPC strategy you want.
import { ElectronDownloadManager } from 'electron-dl-manager';
import { ipcMain } from 'electron';
const manager = new ElectronDownloadManager();
ipcMain.handle('download-file', async (event, args) => {
const { url } = args;
let downloadId
const browserWindow = BrowserWindow.fromId(event.sender.id)
downloadId = await manager.download({
window: browserWindow,
url,
saveAsFilename: 'file.zip',
directory: '/directory/where/to/save',
saveDialogOptions: {
title: 'Save File',
},
callbacks: {
onDownloadStarted: async ({ id, item, resolvedFilename }) => {
browserWindow.webContents.invoke('download-started', {
id,
filename: resolvedFilename,
totalBytes: item.getTotalBytes(),
});
},
onDownloadProgress: async ({ id, item, percentCompleted }) => {
browserWindow.webContents.invoke('download-progress', {
id,
percentCompleted,
bytesReceived: item.getReceivedBytes(),
});
},
onDownloadCompleted: async ({ id, item }) => {
browserWindow.webContents.invoke('download-completed', {
id,
filePath: item.getSavePath(),
});
},
onError: (err, data) => {
}
}
});
manager.pauseDownload(downloadId);
});
API
Class: ElectronDownloadManager
Manages file downloads in an Electron application.
constructor()
constructor(params: DownloadManagerConstructorParams)
interface DownloadManagerConstructorParams {
debugLogger?: (message: string) => void
}
download()
Starts a file download. Returns the id
of the download.
download(params: DownloadParams): Promise<string>
Interface: DownloadParams
interface DownloadParams {
window: BrowserWindow
url: string
callbacks: DownloadManagerCallbacks
downloadURLOptions?: Electron.DownloadURLOptions
saveDialogOptions?: SaveDialogOptions
saveAsFilename?: string
directory?: string
overwrite?: boolean
}
Interface: DownloadManagerCallbacks
interface DownloadManagerCallbacks {
onDownloadStarted: (data: DownloadData) => void
onDownloadProgress: (data: DownloadData) => void
onDownloadCompleted: (data: DownloadData) => void
onDownloadCancelled: (data: DownloadData) => void
onDownloadInterrupted: (data: DownloadData) => void
onError: (error: Error, data?: DownloadData) => void
}
cancelDownload()
Cancels a download.
cancelDownload(id: string): void
pauseDownload()
Pauses a download.
pauseDownload(id: string): void
resumeDownload()
Resumes a download.
resumeDownload(id: string): void
getActiveDownloadCount()
Returns the number of active downloads.
getActiveDownloadCount(): number
getDownloadData()
Returns the download data for a download.
getDownloadData(id: string): DownloadData
Class: DownloadData
Data returned in the callbacks for a download.
Properties
class DownloadData {
id: string
item: DownloadItem
webContents: WebContents
event: Event
resolvedFilename: string
cancelledFromSaveAsDialog?: boolean
percentCompleted: number
downloadRateBytesPerSecond: number
estimatedTimeRemainingSeconds: number
interruptedVia?: 'in-progress' | 'completed'
}
Formatting download progress
You can use the libraries bytes
and dayjs
to format the download progress.
$ npm install bytes dayjs
$ npm install @types/bytes --save-dev
import bytes from 'bytes'
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime';
import duration from 'dayjs/plugin/duration';
dayjs.extend(relativeTime);
dayjs.extend(duration);
const downloadData = manager.getDownloadData(id);
const formattedDownloadRate = bytes(downloadData.downloadRateBytesPerSecond, { unitSeparator: ' ' }) + '/s'
const formattedEstimatedTimeRemaining = dayjs.duration(downloadData.estimatedTimeRemainingSeconds, 'seconds').humanize(true)
isDownloadInProgress()
Returns true if the download is in progress.
isDownloadInProgress(): boolean
isDownloadPaused()
Returns true if the download is paused.
isDownloadPaused(): boolean
isDownloadResumable()
Returns true if the download is resumable.
isDownloadResumable(): boolean
isDownloadCancelled()
Returns true if the download is cancelled.
isDownloadCancelled(): boolean
isDownloadInterrupted()
Returns true if the download is interrupted.
isDownloadInterrupted(): boolean
isDownloadCompleted()
Returns true if the download is completed.
isDownloadCompleted(): boolean
Mock class
If you need to mock out ElectronDownloadManager
in your tests, you can use the ElectronDownloadManagerMock
class.
import { ElectronDownloadManagerMock } from 'electron-dl-manager'
Acknowledgments
This code uses small portions from electron-dl
and is noted in the
code where it is used.
electron-dl
is licensed under the MIT License and is maintained by Sindre Sorhus sindresorhus@gmail.com (https://sindresorhus.com).