# @electron/asar

> Creating Electron app packages

Latest version **4.3.1** (published 2026-09-26) · MIT license · 0 weekly downloads

## Install

```sh
npm install @electron/asar
pnpm add @electron/asar
yarn add @electron/asar
bun add @electron/asar
```

Provides the command `asar`.

## Health

**Score 75/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; has provenance; recently updated; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 4.3.1 |
| Published | 2026-09-26 |
| First published | 2022-10-18 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM |
| Node | >=22.12.0 |
| Dependencies | 2 |
| Unpacked size | 123 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 2866 |
| Maintainers | electron-cfa |

## Links

- npm: https://www.npmjs.com/package/@electron/asar
- Repository: https://github.com/electron/asar
- Issues: https://github.com/electron/asar/issues
- npm.io page: https://npm.io/package/@electron/asar

## Dependencies (2)

- [glob](https://npm.io/package/glob.md) ^13.0.2
- [minimatch](https://npm.io/package/minimatch.md) ^10.0.1

## Recent versions

- 4.3.1 (latest) — 2026-09-26
- 4.3.0 — 2026-08-18
- 4.2.1 — 2026-07-21
- 4.2.0 — 2026-03-31
- 4.1.2 — 2026-03-28
- 4.1.1 — 2026-03-24
- 4.1.0 — 2026-03-05
- 4.0.1 — 2025-08-02
- 4.0.0 — 2025-05-14
- 3.4.1 — 2025-04-07
- 3.4.0 — 2025-04-02
- 3.3.1 — 2025-02-11
- 3.3.0 — 2025-02-10
- 3.2.18 — 2025-01-07
- 3.2.17 — 2024-11-07
- … 17 more at https://npm.io/package/@electron/asar/versions

## README

# @electron/asar - Electron Archive

[![Test](https://github.com/electron/asar/actions/workflows/test.yml/badge.svg)](https://github.com/electron/asar/actions/workflows/test.yml)
[![npm version](http://img.shields.io/npm/v/@electron/asar.svg)](https://npmjs.org/package/@electron/asar)
[![API docs](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fregistry.npmjs.org%2F%40electron%2Fasar%2Flatest&query=%24.version&logo=typescript&logoColor=white&label=API%20Docs)](https://packages.electronjs.org/asar)

ASAR is a simple extensive archive format. It concatenates all files together without compression
(like [`tar`](https://www.gnu.org/software/tar/)) while having random access support.

## Features

* Support random access
* Use JSON to store file information
* Very easy to write a parser
* Store the contents of duplicated files only once

## CLI

### Install

This module requires Node 22.12.0 or later.

```bash
npm install --engine-strict @electron/asar
```

### Usage

```bash
$ asar --help

  Usage: asar [options] [command]

  Commands:

    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


  Options:

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

```

#### Excluding multiple resources from being packed

Given:

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

Exclude: a, b

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

Exclude: a, b, d, f

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

Exclude: a, b, d, f, h

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

## Programmatic usage

For full API usage, see the [API documentation](https://packages.electronjs.org/asar).

### Example

```javascript
import { createPackage } from '@electron/asar';

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

await createPackage(src, dest);
console.log('done.');
```

Please note that there is currently **no** error handling provided!

### Deduplication

Files with identical contents are stored once and shared: the first copy is
written into the archive and every other copy's header entry points at that same
`offset`. Nothing changes for readers — each file still has its own entry, size,
integrity hash, and executable bit — but archives with duplicated contents (a
common shape for bundled `node_modules`) get smaller and pack faster, since the
redundant bytes are never written.

Unpacked files (`unpack` / `unpackDir`) are always written out in full, because
they live on disk outside the archive.

### Transform

You can pass in a `transform` option, that is a function, which either returns
nothing, or a `stream.Transform`. The latter will be used on files that will be
in the `.asar` file to transform them (e.g. compress).

```javascript
import { createPackageWithOptions } from '@electron/asar';

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

function transform (filename) {
  return new CustomTransformStream()
}

await createPackageWithOptions(src, dest, { transform: transform });
console.log('done.');
```

## Format

Asar uses [Pickle][pickle] to safely serialize binary value to file.

The format of asar is very flat:

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

The `header_size` and `header` are serialized with [Pickle][pickle] class, and
`header_size`'s [Pickle][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:

```json
{
   "files": {
      "tmp": {
         "files": {}
      },
      "usr" : {
         "files": {
           "bin": {
             "files": {
               "ls": {
                 "offset": "0",
                 "size": 100,
                 "executable": true,
                 "integrity": {
                   "algorithm": "SHA256",
                   "hash": "...",
                   "blockSize": 1024,
                   "blocks": ["...", "..."]
                 }
               },
               "cd": {
                 "offset": "100",
                 "size": 100,
                 "executable": true,
                 "integrity": {
                   "algorithm": "SHA256",
                   "hash": "...",
                   "blockSize": 1024,
                   "blocks": ["...", "..."]
                 }
               }
             }
           }
         }
      },
      "etc": {
         "files": {
           "hosts": {
             "offset": "200",
             "size": 32,
             "integrity": {
                "algorithm": "SHA256",
                "hash": "...",
                "blockSize": 1024,
                "blocks": ["...", "..."]
              }
           }
         }
      }
   }
}
```

`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.

Files with identical contents share a single copy in the archive, so more than
one entry can point at the same `offset`.

`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.

`integrity` is an object consisting of a few keys:

* A hashing `algorithm`, currently only `SHA256` is supported.
* A hex encoded `hash` value representing the hash of the entire file.
* An array of hex encoded hashes for the `blocks` of the file (i.e. for a blockSize of 4KB, this array contains the hash of every block if you split the file into N 4KB blocks).
* A integer value `blockSize` representing the size in bytes of each block in the `blocks` hashes above.

[pickle]: https://chromium.googlesource.com/chromium/src/+/main/base/pickle.h

---
_Source: https://npm.io/package/@electron/asar · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
