Zip files are a common format for compressed files and folders. Most developers end up using tarballs instead of zip files. But there are certain cases where you are required to use zip files, like uploading a function to AWS Lambda. In this article, I'll demonstrate how to use the adm-zip npm module to create and extract zip files.

Creating a Zip File

The adm-zip npm module exports an AdmZip class. An instance of AdmZip corresponds to a zip file. To create a new zip file, call new AdmZip() with no arguments:

const AdmZip = require('adm-zip');

const file = new AdmZip();

There are several ways you can add files and directories to file. You can add files and directories from your file system by name using file.addLocalFile() and file.addLocalFolder(). For example, below is how you can add a package.json file and a node_modules directory to a zip file:

const AdmZip = require('adm-zip');

const file = new AdmZip();

file.addLocalFile('./package.json');
// The 2nd `node_modules` param is the path to the directory in the zip.
// Without the 2nd param, every dir in `./node_modules` will be a top-level
// directory in the zip file.
file.addLocalFolder('./node_modules', 'node_modules');

You can then write the file using one of two methods: either by converting the zip file to a Node.js buffer using toBuffer(), by using file.writeZip().

// One way to write the zip file: convert it to a buffer and use `fs`
const fs = require('fs');

fs.writeFileSync('output.zip', file.toBuffer());

// Another way to write the zip file: `writeZip()`
file.writeZip('output.zip');

Once you write the output.zip file, you should be able to open it in your zip utility of choice. Below is what the file looks like in engrampa, Xubuntu's default archive manager.

The 2nd parameter to both addLocalFile() and addLocalFolder() is the path to put the file, or the directory's contents, in the zip. For example, if you want to put both package.json and node_modules underneath a project directory, you can run the below script:

const AdmZip = require('adm-zip');

const file = new AdmZip();

file.addLocalFile('./package.json', 'project');
file.addLocalFolder('./node_modules', 'project/node_modules');

const fs = require('fs');

fs.writeFileSync('output.zip', file.toBuffer());

You can also add a file from a raw Node.js buffer using the file.addFile() method. For example, here's how you can add a text file containing the string 'Hello, World' to your zip file, without actually creating a file on your file system.

const AdmZip = require('adm-zip');

const file = new AdmZip();

file.addFile('hello.txt', Buffer.fromString('Hello, World'));

const fs = require('fs');

fs.writeFileSync('output.zip', file.toBuffer());

Working with Existing Files

If you pass a parameter to the AdmZip constructor, adm-zip will parse the file at the given path. For example, below is how you can extract everything from the output.zip file to the directory output.

const AdmZip = require('adm-zip');

const file = new AdmZip('./output.zip');

file.extractAllTo('./output');

You can also extract individual files from the zip file using file.extractEntryTo(). For example, here's how you can pull out the hello.txt file from the zip file and write it to the current directory:

const AdmZip = require('adm-zip');

const file = new AdmZip('./output.zip');

file.extractEntryTo('hello.txt', './');

You can use addLocalFile(), addLocalFolder(), and addFile() with existing files as well.

Moving On

For better or for worse, zip files are commonly used for compression. Some services, like AWS Lambda, require you to work with zip files. Thankfully, the adm-zip npm module makes it easy to create and extract zip files directly from Node.js.

Found a typo or error? Open up a pull request! This post is available as markdown on Github
comments powered by Disqus