Creating & Serving Zip files with Nodejs
Zip files are the first solution we apply whenever we want to share multiple files or a large file with someone be it Gmail/Google Drive or your custom web service we all use Zip files to compress the data.
Zipping a file is of great benefits for you and the end-user both, sometimes for saving storage space or at times the actual network bandwidth.
So, in this article, we will be building a small application in node js which will download user-specific data in the form of a zip file.
For sake of simplicity, we are not adding any database or any session check to it, we will be using a JSON file for the user data, you can check that data here which I generated from mockaroo.
So let’s begin.
Setup
Create a new folder and run the below commands, we will be using jszip for creating zip files
npm init && npm i express && npm i jszip
Add the below code to use express and some initializations, it will just bootstrap the things we need.
const express = require("express"),
JSZip = require("jszip"),
sample_data = require("./sample_data.json");
const app = express();
const zip = new JSZip();
app.listen(3002)
app.get('/download-zip/:user_id', (req, res) => {
let user_id = req.param.user_id;
})
This route is responsible for downloading the actual zip file with user-specific data.
Find User Data
Now, we have to find user data based on the user_id which we have received from the slug param, the method we will be using is the find() method.
let data = sample_data.find((x) => x.id == user_id);
We are now ready with the user data, we have to proceed with the last step which is of creating a file & wrap that in a zip file & download it.
Creating a zip file
So for the original zip file, we want the following folder structure, and the file name will be based on the user’s full name from our sample json file.

const zip = new JSZip();
// Below will create a README.md with the following content
zip.file("README.md", "This is a sample readme file");
you can create folders using the folder() method, and the best part is we can chain them all along.
// below will create a new folder with a new file filename.txt
zip.folder("user_details").file(`filename.txt`, "Hello World!");
Now to make the zip downloadable, we have to encode the zip into base64 encoded ASCII string and serve it over our HTTP response.
We can utilize the zip.generateAsync() method which generates the base64 encoding of our zip file.
zip.generateAsync({ type: "base64" }).then((base64) => {
console.log("Base64 Encoded Data:", base64);
});
And finally, we will consolidate all our code, and the following is our complete code.
const express = require("express"),
JSZip = require("jszip"),
sample_data = require("./sample_data.json");
const app = express();
const zip = new JSZip();
app.get("/download-zip/:user_id", (req, res) => {
let user_id = req.params.user_id;
let data = sample_data.find((x) => x.id == user_id);
zip
.folder("user_details")
.file(`${data.name}_details.txt`, JSON.stringify(data, null, 2));
zip.file("README.md", "This is a sample readme file");
zip.generateAsync({ type: "base64" }).then((base64) => {
let zip = Buffer.from(base64, "base64");
res.writeHead(200, {
"Content-Type": "application/zip",
"Content-disposition": `attachment; filename=user_report.zip`,
});
res.end(zip);
});
});
app.listen(3002);
Explanation
After getting the base64 encoded data, we simply served it over the http response using res.writeHead() & res.end(), with the right content type for the zip file & the content-disposition header.
And we are done 🙂
The code repo can be found here.
Hope you enjoyed reading and learned something out of it, feel free to add your questions or thoughts in the comments.