How to write a file / give it to the user

In the browser

With only javascript, this part won’t work in old browsers, including IE < 10. For those browsers, you can use a flash polyfill, see below.

You can also see this example.

Blob URL / FileSaver

With recent browsers, the easiest way is to use saveAs or a polyfill, see FileSaver.js :

.then(function (blob) {
    saveAs(blob, "");

Under the hood, the polyfill uses the native saveAs from the FileSaver API (on Chrome and IE10+) or use a Blob URL (on Firefox).

Data URI

For older browsers that support data URI, you can also do the following :

zip.generateAsync({type:"base64"}).then(function (base64) {
    location.href="data:application/zip;base64," + base64;

The biggest issue here is that the filenames are very awkward, Firefox generates filenames such as (see bugs 367231 and 532230, and Safari isn’t much better with just Unknown.

Browser support and resulting filename :

Opera Firefox Safari Chrome Internet Explorer
“” random alphanumeric with “.part” extension “Unknown” (no extension) “” on OSX and Linux, just “download” on Windows No


Downloadify uses a small Flash SWF to download files to a user’s computer with a filename that you can choose. Doug Neiner has added the dataType option to allow you to pass a zip for downloading. Follow the Downloadify demo with the following changes:

zip = new JSZip();
zip.file("Hello.", "hello.txt");

zip.generateAsync({type:"base64"}).then(function (base64) {
    data: function(){
        return base64;
    dataType: 'base64'

Deprecated google gears

Franz Buchinger has written a brilliant tutorial on using JSZip with Google Gears (part 2). If you want to let your Gears users download several files at once I really recommend having a look at some of his examples.

In nodejs

JSZip can generate Buffers so you can do the following :

var fs = require("fs");
var JSZip = require("jszip");

var zip = new JSZip();
// zip.file("file", content);
// ... and other manipulations

.on('finish', function () {
    // JSZip generates a readable stream with a "end" event,
    // but is piped here in a writable stream which emits a "finish" event.
    console.log(" written.");