npm.io
0.2.3 • Published 6d agoCLI

extension-from-store

Licence
MIT
Version
0.2.3
Deps
2
Size
92 kB
Vulns
0
Weekly
2.4K

Download public browser extensions from official stores

extension-from-store Version Downloads workflow provenance

  • Chrome Web Store, Microsoft Edge Add-ons, Firefox AMO
  • Promise-based API
  • Node.js + CLI support

Install

npm i extension-from-store

Usage

Via Node.js:

import {fetchExtensionFromStore} from 'extension-from-store'

const url =
  'https://chromewebstore.google.com/detail/adblock-plus-free-ad-bloc/cfhdojbkjhnklbpkdaibdccddilifddb'

const options = {
  outDir: './extensions',
  userAgent: 'my-tool/1.0.0',
  extract: true,
  logger: {
    onInfo: (message) => console.log(message),
    onWarn: (message) => console.warn(message),
    onError: (message, error) => console.error(message, error)
  }
}

await fetchExtensionFromStore(url, options)

Via browser entrypoint:

import {fetchExtensionFromStoreBrowser} from 'extension-from-store/browser'

const result = await fetchExtensionFromStoreBrowser(
  'https://chromewebstore.google.com/detail/adblock-plus-free-ad-bloc/cfhdojbkjhnklbpkdaibdccddilifddb',
)

console.log(result.meta)
console.log(result.files.find((file) => file.path === 'manifest.json')?.text)

The browser entry keeps everything in memory and returns archive bytes, extracted files, and parsed manifest metadata. It does not write to disk.

Via core helpers:

import {
  detectStoreFromUrl,
  extractChromeIdFromUrl,
  getChromeDownloadUrl,
  parseManifestInfo,
  stripCrxHeader,
} from 'extension-from-store/core'

Via CLI (default command is fetch):

npx extension-from-store --url "<store-item-url>"
npx extension-from-store --url "<store-item-url>" --out ./my-exts
npx extension-from-store --url "<store-item-url>" --version 2.1.0 --extract
npx extension-from-store --url "<store-item-url>" --extract

The store is detected from the URL.

Output

<out>/
  <identifier>@<resolved-version>/
    extension.meta.json
    ...

If the target folder already exists, the operation fails.

By default, extension-from-store downloads the archive without extraction. When you pass --extract, it unpacks the archive and writes metadata.

When extraction is disabled, the archive is saved as:

<out>/<identifier>[@<version>].crx
<out>/<identifier>[@<version>].xpi

Extraction Rules

  • .crx: strip CRX header, extract ZIP payload
  • .xpi: treat as ZIP
  • No normalization, no rewriting, no formatting

extension.meta.json

{
  "store": "chrome | edge | firefox",
  "identifier": "<identifier derived from the URL>",
  "version": "<resolved version>",
  "manifestVersion": 2 | 3
}

This file is written by extension-from-store to the same folder as the extracted files.

CLI Flags

Flag Required Description
--url <string> Yes Extension URL
--out <path> No Output directory (default: ./extensions)
--version <string> No Version hint
--user-agent <string> No Override user agent
--extract No Extract after download (default: download only)
--quiet No Suppress info logs
--verbose No Emit verbose info logs
--json No JSON lines output to stdout

Logging

Library logging is opt-in via the logger hooks. The library never writes directly to stdout/stderr.

Exit Codes

  • 0 success
  • 1 invalid input
  • 2 unsupported store
  • 3 not found / not public
  • 4 download failed
  • 5 extraction failed
  • 6 filesystem conflict
  • 7 store incompatibility

License

MIT (c) Cezar Augusto.

Keywords