A fast and flexible Node.js tool for packaging files and browser extensions into .zip, .tar.gz, and .crx archives with automatic project detection, templated filenames, and cross-platform support.
-
π¦ Pack folders or files into:
.zip.tar.gz.crx(Chrome/Edge/Brave/Chromium extensions)
-
π§ Automatic project detection (
package.json,manifest.json) -
π§Ή Ignore patterns support via
@unsonet/ignore-patterns -
π§© Template-based filenames (
{{name}},{{version}}, etc.) -
π Cross-platform (Windows / macOS / Linux)
-
π§ͺ CLI + programmatic API
-
π Auto browser executable resolution for CRX packaging
-
β‘ Safe staging into temp directories
npm install @unsonet/packor
yarn add @unsonet/packnpx @unsonet/pack ./distnpx @unsonet/pack ./dist --ext zip
npx @unsonet/pack ./dist --ext tar.gz
npx @unsonet/pack ./dist --ext crxnpx @unsonet/pack ./dist ./assets ./manifest.jsonnpx @unsonet/pack ./dist --output ./releasenpx @unsonet/pack ./dist --name "{{name}}-v{{version}}"npx @unsonet/pack ./dist --ignore "node_modules,dist,test"Or disable ignore:
--ignore nullnpx @unsonet/pack ./dist --forceSupported browsers:
- chrome
- chromium
- edge
- brave
- opera
npx @unsonet/pack ./extension --ext crx --browser chromenpx @unsonet/pack ./extension --ext crx --browserPath "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"- Browser must support
--pack-extension manifest.jsonmust exist in input (or detected in project tree)
import { pack } from '@unsonet/pack';
const result = await pack({
input: './dist',
ext: 'zip',
});
console.log(result.outputPath);await pack({
input: ['./dist', './assets'],
ext: 'zip',
});await pack({
input: string | string[];
output?: string;
ext?: 'zip' | 'tar.gz' | 'crx';
name?: string;
force?: boolean;
cwd?: string;
ignore?: string | null;
browser?: 'chrome' | 'chromium' | 'edge' | 'brave' | 'opera';
browserPath?: string;
startSymbols?: string;
endSymbols?: string;
});The result of packaging:
interface PackResult {
outputPath: string;
filename: string;
extension: 'zip' | 'tar.gz' | 'crx';
createdAt: string;
inputPaths: string[];
browserPath?: string;
}You can customize output filenames using templates:
| Variable | Description |
|---|---|
name |
Project name |
version |
Project version |
version-kebab |
version with dots replaced by - |
version-snake |
version with dots replaced by _ |
folder |
project folder name |
timestamp |
ISO timestamp safe for filenames |
await pack({
input: './dist',
name: '{{name}}-{{version}}-{{timestamp}}',
});Automatically reads:
nameversion
- detects extension mode
- reads version if present
Fallback:
- folder name
localversion
Uses @unsonet/ignore-patterns.
Examples:
ignore: "node_modules,dist,.git"or
ignore: null // disables ignoringCRX mode requires:
- valid browser executable
manifest.json- valid extension structure
Throws if:
- browser not found
- manifest missing
- browser fails to generate
.crx
Internally the library:
- Creates temp directory
- Copies input into
/payload - Applies ignore rules
- Packs archive
- Cleans up automatically
| Feature | Windows | macOS | Linux |
|---|---|---|---|
| ZIP | β | β | β |
| TAR.GZ | β | β | β |
| CRX | β | β | β |
Common errors:
- Input path not found
- Output file already exists (use
force) zipnot installedtarnot installed- Browser executable not found
- Invalid extension type
import { pack } from '@unsonet/pack';
await pack({
input: './dist',
ext: 'zip',
ignore: 'node_modules',
name: '{{name}}-prod-{{version}}',
force: true,
});After install:
pack --help(or via npx)
MIT