# Application packaging To protect your app's resources and source code from the users, you can choose to package your app into an [asar][asar] archive with little changes to your source code. ## Generating `asar` archive An [asar][asar] archive is a simple tar-like format that concatenates files into a single file, atom-shell can read arbitrary file in it without unpacking the whole file. Following is the steps to package your app into an `asar` archive: ### 1. Install the asar utility ```bash $ npm install -g asar ``` ### 2. Package with `asar pack` ```bash $ asar pack your-app app.asar ``` ## Using `asar` archives In atom-shell there are two sets of APIs: Node APIs provided by Node.js, and Web APIs provided by Chromium. Both APIs support reading files from `asar` archives. ### Node API With special patches in atom-shell, Node APIs like `fs.readFile` and `require` treat `asar` archives as virtual directories, and the files in it as normal files in the filesystem. For example, suppose we have an `example.asar` archive under `/path/to`: ```bash $ asar list /path/to/example.asar /app.js /file.txt /dir/module.js /static/index.html /static/main.css /static/jquery.min.js ``` Read a file in the `asar` archive: ```javascript var fs = require('fs'); fs.readFileSync('/path/to/example.asar/file.txt'); ``` List all files under the root of the archive: ```javascript var fs = require('fs'); fs.readdirSync('/path/to/example.asar'); ``` Use a module from the archive: ```javascript require('/path/to/example.asar/dir/module.js'); ``` ### Web API In a web page, files in archive can be requested by using the `asar:` protocol. Like the Node API, `asar` archives are treated as directories. For example, to get a file with `$.get`: ```html ``` The `asar:` protocol can also be used to request normal files in filesystem, just like the `file:` protocol. But unlike `file:` protocol, there are no slashes (`//`) after `asar:`. You can also display a web page in an `asar` archive with `BrowserWindow`: ```javascript var BrowserWindow = require('browser-window'); var win = new BrowserWindow({width: 800, height: 600}); win.loadUrl('asar:/path/to/example.asar/static/index.html'); ``` ### Treating `asar` archive as normal file For some cases like verifying the `asar` archive's checksum, we need to read the content of `asar` archive as file. For this purpose you can use the built-in `original-fs` module which provides original `fs` APIs without `asar` support: ```javascript var originalFs = require('original-fs'); originalFs.readFileSync('/path/to/example.asar'); ``` ## Limitations on Node API Even though we tried hard to make `asar` archives in the Node API work like directories as much as possible, there are still limitations due to the low-level nature of the Node API. ### Archives are read only The archives can not be modified so all Node APIs that can modify files will not work with `asar` archives. ### Working directory can not be set to directories in archive Though `asar` archives are treated as directories, there are no actual directories in the filesystem, so you can never set the working directory to directories in `asar` archives, passing them to `cwd` option of some APIs will also cause errors. ### Extra unpacking on some APIs Most `fs` APIs can read file or get file's information from `asar` archives without unpacking, but for some APIs that rely on passing the real file path to underlying system calls, atom-shell will extract the needed file into a temporary file and pass the path of the temporary file to the APIs to make them work. This adds a little overhead for those APIs. APIs that requires extra unpacking are: * `child_process.execFile` * `child_process.fork` * `fs.open` * `fs.openSync` * `process.dlopen` - Used by `require` on native modules ### Fake stat information of `fs.stat` The `Stats` object returned by `fs.stat` and its friends on files in `asar` archives is generated by guessing, because those files do not exist on the filesystem. So you should not trust the `Stats` object except for getting file size and checking file type. [asar]: https://github.com/atom/asar