{"id":11517,"library":"pacote","title":"Pacote: JavaScript Package Downloader","description":"Pacote is a robust JavaScript library designed for programmatically fetching package manifests and tarballs, primarily from the npm registry but also supporting various other package specifiers like Git repositories, local directories, and tarball URLs. It is the underlying package fetching mechanism used by the npm CLI itself, ensuring high compatibility with npm's ecosystem. The current stable version is 21.5.0, released in March 2026, and the project demonstrates an active release cadence with frequent updates across major versions (e.g., v19, v20, v21 receiving simultaneous updates). Key differentiators include its ability to resolve any npm-compatible package specifier, simulate packument data for non-registry sources, and run `prepare` scripts for Git or directory-based packages to replicate the publishing process. It provides APIs for resolving package URLs, extracting contents to a directory, fetching manifests, and downloading tarball data as buffers or streams.","status":"active","version":"21.5.0","language":"javascript","source_language":"en","source_url":"https://github.com/npm/pacote","tags":["javascript","packages","npm","git"],"install":[{"cmd":"npm install pacote","lang":"bash","label":"npm"},{"cmd":"yarn add pacote","lang":"bash","label":"yarn"},{"cmd":"pnpm add pacote","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core dependency for handling tarball extraction and creation.","package":"tar","optional":false},{"reason":"Required for interacting with Git repositories as package sources.","package":"@npmcli/git","optional":false},{"reason":"Used for understanding the contents of installed packages, especially for directory and tarball sources.","package":"@npmcli/installed-package-contents","optional":false}],"imports":[{"note":"Pacote is typically imported as a default object containing all its functions.","wrong":"import { pacote } from 'pacote'; // Incorrect named import, pacote exports a default object.","symbol":"pacote","correct":"import pacote from 'pacote';"},{"note":"CommonJS require style is fully supported and demonstrated in the official documentation.","wrong":null,"symbol":"pacote (CommonJS)","correct":"const pacote = require('pacote');"},{"note":"All API functions like `manifest`, `extract`, `tarball` are methods of the main `pacote` object.","wrong":"import { manifest } from 'pacote'; // Manifest is a method on the default export, not a named export.","symbol":"pacote.manifest","correct":"import pacote from 'pacote';\nconst manifest = await pacote.manifest('foo@latest');"}],"quickstart":{"code":"const pacote = require('pacote');\nconst path = require('path');\nconst fs = require('fs/promises');\n\nasync function main() {\n  const packageName = 'lodash';\n  const packageVersion = '4.17.21';\n  const gitSpec = 'github:npm/cli';\n  const tarballUrl = 'https://registry.npmjs.org/is-odd/-/is-odd-3.0.1.tgz';\n\n  console.log(`--- Fetching manifest for ${packageName}@${packageVersion} ---`);\n  try {\n    const manifest = await pacote.manifest(`${packageName}@${packageVersion}`);\n    console.log(`Got manifest for ${manifest.name}@${manifest.version}`);\n    console.log(`Dependencies: ${Object.keys(manifest.dependencies || {}).join(', ') || 'None'}`);\n  } catch (error) {\n    console.error(`Failed to fetch manifest: ${error.message}`);\n  }\n\n  console.log(`\\n--- Extracting ${gitSpec} to a temporary path ---`);\n  const tempExtractPath = path.join(__dirname, 'temp-extracted-repo');\n  try {\n    await fs.mkdir(tempExtractPath, { recursive: true });\n    const { from, resolved, integrity } = await pacote.extract(gitSpec, tempExtractPath);\n    console.log(`Extracted '${from}' (resolved to '${resolved}') with integrity '${integrity}' to '${tempExtractPath}'`);\n    const files = await fs.readdir(tempExtractPath);\n    console.log(`Extracted files (first 5): ${files.slice(0, 5).join(', ')}...`);\n  } catch (error) {\n    console.error(`Failed to extract package: ${error.message}`);\n  } finally {\n    await fs.rm(tempExtractPath, { recursive: true, force: true });\n  }\n\n  console.log(`\\n--- Downloading tarball from ${tarballUrl} ---`);\n  try {\n    const tarballData = await pacote.tarball(tarballUrl);\n    console.log(`Got ${tarballData.length} bytes of tarball data. Resolved URL: ${tarballData.resolved}`);\n  } catch (error) {\n    console.error(`Failed to download tarball: ${error.message}`);\n  }\n}\n\nmain().catch(console.error);","lang":"javascript","description":"Demonstrates fetching a package manifest, extracting a package from a Git repository, and downloading a tarball directly from a URL using `pacote`'s core asynchronous APIs."},"warnings":[{"fix":"Upgrade your Node.js installation to version 20.17.0 or higher (or 22.9.0+).","message":"Pacote now requires Node.js version `^20.17.0 || >=22.9.0`. Older Node.js environments will result in runtime errors. Ensure your environment meets these minimum requirements.","severity":"breaking","affected_versions":">=20.0.0"},{"fix":"Be aware of `prepare` script execution; ensure your environment can run these scripts safely and efficiently. If fetching from untrusted sources, consider security implications.","message":"When fetching packages from Git repositories or local directories, Pacote automatically executes `prepare` scripts to simulate the build process as if it were being published to the registry. This can have side effects, introduce unexpected build times, or require specific environment configurations if not properly anticipated.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Carefully review `pacote` options against npm CLI documentation. For security and control, explicitly set `allow*` options to permit desired package source types.","message":"Pacote's configuration options (`opts` parameter) mirror npm's CLI configuration. Incorrectly setting options like `cache`, `registry`, or authentication tokens can lead to unexpected fetching behavior, authentication failures, or network errors. Utilize the recently introduced `allowRegistry`, `allowRemote`, `allowFile`, `allowDirectory`, and `allowGit` options to explicitly control allowed package sources, as misconfiguration could unintentionally block valid package types.","severity":"gotcha","affected_versions":">=21.1.0"},{"fix":"Always inspect the `integrity` and `resolved` fields returned by Pacote's APIs to ensure the fetched package matches expectations, particularly for Git-based dependencies.","message":"The `integrity` field, especially for Git sources, can be complex. Recent versions (e.g., v21.3.1 fix for `git ref matches expected sha`) highlight potential for inconsistencies in how Git references are resolved. Always verify the resolved `integrity` and `resolved` fields for critical dependencies.","severity":"gotcha","affected_versions":">=19.0.0"},{"fix":"Monitor network behavior and error logs after upgrading to ensure attestation bundle fetching and validation are working as expected within your environment and with your chosen registry.","message":"The introduction of 'attestation bundles' in v21.5.0 provides a security layer. While beneficial, it might introduce overhead or unexpected network requests if the registry or network setup doesn't fully support it, potentially impacting performance or causing errors if validation fails.","severity":"gotcha","affected_versions":">=21.5.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Inspect the full error output for details from the failed script. Ensure the environment has necessary build tools and dependencies for the package's `prepare` script. You might need to adjust options to skip `prepare` if not critical.","cause":"Often occurs when `prepare` scripts within a fetched package (especially from Git or local directory) fail during execution.","error":"Error: Command failed with exit code 1"},{"fix":"Verify the package specifier against `npm-package-arg` documentation and examples. Ensure correct syntax for versions, ranges, Git URLs, and local paths.","cause":"The provided package specifier (e.g., `foo@^1.0`, `github:user/repo`, `file:../path`) is malformed or not recognized by Pacote/npm-package-arg.","error":"Error: Unsupported specifier: <your-package-specifier>"},{"fix":"Check your network connection, npm proxy settings, and ensure your `.npmrc` or programmatic options have the correct `registry` and authentication (e.g., `_authToken`) configured.","cause":"Network issues, incorrect registry configuration, or proxy problems preventing connection to the npm registry or other package sources.","error":"ETIMEDOUT"},{"fix":"Ensure `pacote` is listed in `dependencies` and `npm install` has been run. Verify import statement (`const pacote = require('pacote');` for CJS or `import pacote from 'pacote';` for ESM) matches your project's module system and Node.js configuration.","cause":"Package `pacote` is not installed, or there is a module resolution issue (e.g., wrong import path, CJS/ESM mismatch in an improperly configured project).","error":"Error: Cannot find module 'pacote'"}],"ecosystem":"npm"}