Turning several browser files into one download usually leads to a backend endpoint: upload the files, create an archive on the server, then send it back.
For files that are already in the browser, that round trip is unnecessary. You can create the ZIP locally and keep every file on the user's device.
In this tutorial, we'll use Eazip, an open-source JavaScript toolkit for ZIP downloads. Its Core package creates and downloads the archive entirely in the browser.
Install Eazip
npm install @eazip/core
Add a file picker
<input id="files" type="file" multiple />
<button id="download" type="button">Download as ZIP</button>
Create the ZIP
import { createZip } from '@eazip/core';
const fileInput = document.querySelector('#files');
const downloadButton = document.querySelector('#download');
if (!(fileInput instanceof HTMLInputElement)) {
throw new Error('File input not found');
}
if (!(downloadButton instanceof HTMLButtonElement)) {
throw new Error('Download button not found');
}
downloadButton.addEventListener('click', async () => {
if (!fileInput.files?.length) return;
const result = await createZip({
files: fileInput.files,
zipName: 'selected-files.zip',
});
result.download();
});
FileList is accepted directly. createZip() packages the selected files in the browser and resolves when the archive is ready to download.
That means:
- no upload before the download can begin
- no backend code to write or maintain
- no temporary archive to store and clean up
Keep folders and rename entries
Pass source objects when the path inside the ZIP should differ from the original browser filename:
const result = await createZip({
files: [
{ file: reportFile, filename: 'reports/annual.pdf' },
{ file: chartBlob, filename: 'reports/chart.png' },
],
zipName: 'reports.zip',
});
result.download();
Eazip also accepts File, Blob, remote URL strings, and { url, filename } objects.
What about remote URLs?
The browser can also package remote files, but those URLs must allow your application's origin through CORS. Private files should use short-lived signed URLs rather than storage credentials in frontend code.
For multi-GB archives or thousands of URLs, browser memory and tab lifetime can become limiting factors. In those cases, you can switch to Eazip Cloud that handles the large ZIP job outside the browser with just two option parameters — no backend code required.
The full browser guide is available in the Eazip documentation.
Where are you creating ZIP downloads today: in the browser, an API route, or a background worker?
Top comments (0)