Sign Up for Free

RunKit +

Try any Node.js package right in your browser

This is a playground to test code. It runs a full Node.js environment and already has all of npm’s 1,000,000+ packages pre-installed, including @develar/asar with all npm packages installed. Try it out:

var asar = require("@develar/asar")

This service is provided by RunKit and is not affiliated with npm, Inc or the package authors.

@develar/asar v0.13.1

Creating atom-shell app packages

asar - Electron Archive

build status dependencies npm version

Asar is a simple extensive archive format, it works like tar that concatenates all files together without compression, while having random access support.


  • Support random access
  • Use JSON to store files' information
  • Very easy to write a parser

Command line utility


$ npm install asar


$ asar --help

  Usage: asar [options] [command]


    pack|p <dir> <output>
       create asar archive

    list|l <archive>
       list files of asar archive

    extract-file|ef <archive> <filename>
       extract one file from archive

    extract|e <archive> <dest>
       extract archive


    -h, --help     output usage information
    -V, --version  output the version number

Excluding multiple resources from being packed


(a) ├── x1
(b) ├── x2
(c) ├── y3
(d) │   ├── x1
(e) │   └── z1
(f) │       └── x2
(g) └── z4
(h)     └── w1

Exclude: a, b

$ asar pack app app.asar --unpack-dir "{x1,x2}"

Exclude: a, b, d, f

$ asar pack app app.asar --unpack-dir "**/{x1,x2}"

Exclude: a, b, d, f, h

$ asar pack app app.asar --unpack-dir "{**/x1,**/x2,z4/w1}"

Using programatically


var asar = require('asar');

var src = 'some/path/';
var dest = 'name.asar';

asar.createPackage(src, dest, function() {

Please note that there is currently no error handling provided!

Using with grunt

There is also an unofficial grunt plugin to generate asar archives at bwin/grunt-asar.


Asar uses Pickle to safely serialize binary value to file, there is also a node.js binding of Pickle class.

The format of asar is very flat:

| UInt32: header_size | String: header | Bytes: file1 | ... | Bytes: file42 |

The header_size and header are serialized with Pickle class, and header_size's Pickle object is 8 bytes.

The header is a JSON string, and the header_size is the size of header's Pickle object.

Structure of header is something like this:

   "files": {
      "tmp": {
         "files": {}
      "usr" : {
         "files": {
           "bin": {
             "files": {
               "ls": {
                 "offset": "0",
                 "size": 100,
                 "executable": true
               "cd": {
                 "offset": "100",
                 "size": 100,
                 "executable": true
      "etc": {
         "files": {
           "hosts": {
             "offset": "200",
             "size": 32

offset and size records the information to read the file from archive, the offset starts from 0 so you have to manually add the size of header_size and header to the offset to get the real offset of the file.

offset is a UINT64 number represented in string, because there is no way to precisely represent UINT64 in JavaScript Number. size is a JavaScript Number that is no larger than Number.MAX_SAFE_INTEGER, which has a value of 9007199254740991 and is about 8PB in size. We didn't store size in UINT64 because file size in Node.js is represented as Number and it is not safe to convert Number to UINT64.

RunKit is a free, in-browser JavaScript dev environment for prototyping Node.js code, with every npm package installed. Sign up to share your code.
Sign Up for Free