<?xml version="1.0" encoding="UTF-8"?>
<spec xmlns="https://vibevm.org/spec/1">
  <title>Package Metadata</title>
  <p p="1">Package *metadata* describes a package for its consumers: who wrote it, where its repository is, and what versions of it have been published. It also contains a description of each *version* of a package present in the registry, listing its dependencies, giving the url of its tarball, and so on. Package metadata is useful for finding packages and for installing them.</p>
  <p p="2">You can request _package metadata_ from this endpoint:</p>
  <p p="3">`GET https://registry.npmjs.org/:package`</p>
  <p p="4">The registry responds with a JSON-formatted string containing metadata for the package named, either in full or abbreviated form depending on what you request in the `Accept` header. If you provide no Accept header, the full document is returned. To request an _abbreviated_ document with only the fields required to support installation, set the `Accept` header in your request to the following string:</p>
  <p p="5">`application/vnd.npm.install-v1+json`</p>
  <p p="6">A more typical accept header might request json as a fallback, like this:</p>
  <p p="7">`application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*`</p>
  <p p="8">The formats are described in detail below, but you can compare them by making requests using any tool you like. To request package metadata documents with [httpie](https://httpie.org):</p>
  <fence lang="shell" p="9">http GET https://registry.npmjs.org/npm
http GET https://registry.npmjs.org/npm Accept:application/vnd.npm.install-v1+json</fence>
  <p p="10">With the less user-friendly but ubiquitous curl:</p>
  <fence lang="shell" p="11">curl -H "Accept: application/vnd.npm.install-v1+json" https://registry.npmjs.org/npm</fence>
  <p p="12">`tiny-tarball` is a small package with only one version and no dependencies. Its abbreviated metadata looks like this:</p>
  <fence lang="json" p="13">{
    "dist-tags": {
        "latest": "1.0.0"
    },
    "modified": "2015-05-16T22:27:54.741Z",
    "name": "tiny-tarball",
    "versions": {
        "1.0.0": {
            "_hasShrinkwrap": false,
            "directories": {},
            "dist": {
                "shasum": "bbf102d5ae73afe2c553295e0fb02230216f65b1",
                "tarball": "https://registry.npmjs.org/tiny-tarball/-/tiny-tarball-1.0.0.tgz"
            },
            "name": "tiny-tarball",
            "version": "1.0.0"
        }
    }
}</fence>
  <p p="14">The full metadata for `tiny-tarball` looks like this:</p>
  <fence lang="json" p="15">{
    "_attachments": {},
    "_id": "tiny-tarball",
    "_rev": "3-085759e977d42299e64a35aedc17d250",
    "author": {
        "email": "ben@npmjs.com",
        "name": "Ben Coe"
    },
    "description": "tiny tarball used for health checks",
    "dist-tags": {
        "latest": "1.0.0"
    },
    "license": "ISC",
    "maintainers": [
        {
            "email": "ben@npmjs.com",
            "name": "bcoe"
        }
    ],
    "name": "tiny-tarball",
    "readme": "# TinyTarball\n\ntiny-tarball used for health checks\n\n**don't unpublish me!**\n",
    "readmeFilename": "README.md",
    "time": {
        "1.0.0": "2015-03-24T00:12:24.039Z",
        "created": "2015-03-24T00:12:24.039Z",
        "modified": "2015-05-16T22:27:54.741Z"
    },
    "versions": {
        "1.0.0": {
            "_from": ".",
            "_id": "tiny-tarball@1.0.0",
            "_nodeVersion": "1.5.0",
            "_npmUser": {
                "email": "bencoe@gmail.com",
                "name": "bcoe"
            },
            "_npmVersion": "2.7.0",
            "_shasum": "bbf102d5ae73afe2c553295e0fb02230216f65b1",
            "author": {
                "email": "ben@npmjs.com",
                "name": "Ben Coe"
            },
            "description": "tiny tarball used for health checks",
            "directories": {},
            "dist": {
                "shasum": "bbf102d5ae73afe2c553295e0fb02230216f65b1",
                "tarball": "https://registry.npmjs.org/tiny-tarball/-/tiny-tarball-1.0.0.tgz"
            },
            "license": "ISC",
            "main": "index.js",
            "maintainers": [
                {
                    "email": "bencoe@gmail.com",
                    "name": "bcoe"
                }
            ],
            "name": "tiny-tarball",
            "scripts": {
                "test": "echo \"Error: no test specified\" &amp;&amp; exit 1"
            },
            "version": "1.0.0"
        }
    }
}</fence>
  <p p="16">The size difference is more exaggerated for packages with many versions or many stars, such as `npm` or `lodash`. For some packages in the registry, the full metadata is over 10MB uncompressed. If the information you wish to use for a package is present in the abbreviated version, you should prefer it over the full version.</p>
  <section title="Components of the metadata">
    <section title="human">
      <p p="17">Human objects have at least one of the following fields defined:</p>
      <list ordered="false" p="18">
        <item>`name`: a freeform string name</item>
        <item>`email`: an email address</item>
        <item>`url`: a url for a web page with more information about the author</item>
      </list>
      <p p="19">Historically no validation has been performed on those fields; they are generated by parsing user-provided data in package.json at publication time.</p>
      <p p="20">Example:</p>
      <fence lang="json" p="21">{
    "email": "ben@example.com",
    "name": "Ben The Example"
}</fence>
    </section>
    <section title="dist">
      <p p="22">The `dist` object is generated by npm and may be relied upon. Each dist object has at least two fields:</p>
      <list ordered="false" p="23">
        <item>`tarball`: the url of the tarball containing the payload for this package</item>
        <item>`shasum`: the SHA-1 sum of the tarball</item>
        <item>`integrity`: since Apr 2017, string in the format `&lt;hashAlgorithm&gt;-&lt;base64-hash&gt;`, refer the [Subresource Integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) and [cacache](https://github.com/npm/cacache#integrity) package for more</item>
        <item>`fileCount`: since Feb 2018, the number of files in the tarball, folder excluded</item>
        <item>`unpackedSize`: since Feb 2018, the total byte of the unpacked files in the tarball</item>
        <item>`npm-signature`: since Apr 2018, a PGP signature of `&lt;package&gt;@&lt;version&gt;:&lt;integrity&gt;`, refer the npm [blog](https://blog.npmjs.org/post/172999548390/new-pgp-machinery) and [doc](https://docs.npmjs.com/about-pgp-signatures-for-packages-in-the-public-registry) for more</item>
        <item>(in the future) a SHA-2 512 sum of the tarball</item>
      </list>
      <p p="24">Example:</p>
      <fence lang="json" p="25">{
    "shasum": "bbf102d5ae73afe2c553295e0fb02230216f65b1",
    "tarball": "https://registry.npmjs.org/tiny-tarball/-/tiny-tarball-1.0.0.tgz"
}</fence>
    </section>
  </section>
  <section title="repository">
    <p p="26">An object specifying the repository where the source for this package might be found. It has two fields:</p>
    <fence lang="json" p="27">"repository": {
    "type": "git",
    "url": "git://github.com/npm/npm.git"
}</fence>
  </section>
  <section title="Abbreviated metadata format">
    <p p="28">This form of the package metadata exists to provide a smaller payload designed to support installation. It contains an allow list of fields from the full metadata set. The top-level fields are:</p>
    <list ordered="false" p="29">
      <item>`name`: the package name</item>
      <item>`modified`: ISO string of the last time this package was modified</item>
      <item>`dist-tags`: a mapping of dist tags to the versions they point to</item>
      <item>`versions`: a mapping of version numbers to objects containing the information needed to install that version</item>
    </list>
    <p p="30">Example:</p>
    <fence lang="json" p="31">{
    "name": "&lt;package-name&gt;",
    "modified": "2017-03-21T21:40:18.939Z",
    "dist-tags": {
        "latest": "&lt;semver-compliant version string&gt;",
        "&lt;dist-tag-name&gt;": "&lt;semver-compliant version string&gt;"
    },
    "versions": {
        "&lt;version&gt;": &lt;version object&gt;,
        "&lt;version&gt;": &lt;version object&gt;
    }
}</fence>
    <section title="Abbreviated version object">
      <p p="32">Each abbreviated version object contains the following fields:</p>
      <list ordered="false" p="33">
        <item>`name`: the package name</item>
        <item>`version`: the version string for this version</item>
        <item>`deprecated`: the deprecation warnings message of this version</item>
        <item>`dependencies`: a mapping of other packages this version depends on to the required semver ranges</item>
        <item>`acceptDependencies`: a mapping of packages to alternative versions that can be used</item>
        <item>`optionalDependencies`:  an object mapping package names to the required semver ranges of _optional_ dependencies</item>
        <item>`devDependencies`: a mapping of package names to the required semver ranges of _development_ dependencies</item>
        <item>`bundleDependencies`: an array of dependencies bundled with this version</item>
        <item>`peerDependencies`: a mapping of package names to the required semver ranges of _peer_ dependencies</item>
        <item>`peerDependenciesMeta`: a mapping of peer package names to additional meta information for those peers</item>
        <item>`bin`: a mapping of bin commands to set up for this version</item>
        <item>`directories`: an array of directories included by this version</item>
        <item>`dist`: a [dist object](#dist)</item>
        <item>`engines`: the node engines required for this version to run, if specified</item>
        <item>`_hasShrinkwrap`: `true` if this version is known to have a shrinkwrap that must be used to install it; `false` if this version is known not to have a shrinkwrap. If this field is undefined, the client must determine through other means if a shrinkwrap exists.</item>
        <item>`hasInstallScript`: `true` if this version has the `install` scripts.</item>
        <item>`funding`: object containing a URL that provides up-to-date information about ways to help fund development of your package, or a string URL, or an array of these</item>
        <item>`cpu`: an array of CPU architectures supported by the package</item>
        <item>`os`: an array of operating systems supported by the package</item>
      </list>
      <p p="34">The `name`, `version`, and `dist` fields will always be present. The others will be absent if they are irrelevant for this package version.</p>
    </section>
  </section>
  <section title="Full metadata format">
    <p p="35">Top-level fields, in lexical order:</p>
    <list ordered="false" p="36">
      <item>`_id`: the package name, used as an ID in CouchDB</item>
      <item>`_rev`: the revision number of this version of the document in CouchDB</item>
      <item>`dist-tags`: a mapping of dist tags to versions. Every package will have a `latest` tag defined.</item>
      <item>`name`: the package name</item>
      <item>`time`: an object mapping versions to the time published, along with `created` and `modified` timestamps</item>
      <item>`users`: an object whose keys are the npm user names of people who have starred this package</item>
      <item>`versions`: a mapping of semver-compliant version numbers to version data</item>
    </list>
    <p p="37">The following fields are hoisted to the top-level of the package json from the latest version published:</p>
    <list ordered="false" p="38">
      <item>`author`: [human](#human) object</item>
      <item>`bugs`: url</item>
      <item>`contributors`: array of [human](#human) objects</item>
      <item>`description`: a short description of the package</item>
      <item>`homepage`: url</item>
      <item>`keywords`: array of string keywords</item>
      <item>`license`: the [SPDX identifier](https://spdx.org/licenses/) of the package's license</item>
      <item>`maintainers`: array of [human](#human) objects for people with permission to publish this package; not authoritative but informational</item>
      <item>`readme`: the first 64K of the README data for the most-recently published version of the package</item>
      <item>`readmeFilename`: The name of the file from which the readme data was taken.</item>
      <item>`repository`: as given in package.json, for the latest version</item>
    </list>
    <p p="39">Each package version data object contains all of the fields in the abbreviated document, except `hasInstallScript`, plus the fields listed above as hosted, plus at least the following:</p>
    <list ordered="false" p="40">
      <item>`_id`: `package@version`, such as `npm@1.0.0`</item>
      <item>`_nodeVersion`: the version of node used to publish this</item>
      <item>`_npmUser`: the author object for the npm user who published this version</item>
      <item>`_npmVersion`: the version of the npm client used to publish this</item>
      <item>`main`: the package's entry point (e.g., index.js or main.js)</item>
    </list>
    <p p="41">The full version object will also contain any other fields the package publisher chose to include in their package.json file for that version.</p>
  </section>
</spec>
