Build configuration
Configuring Chainguard Libraries for JavaScript on your workstation
For the complete documentation index, see llms.txt.
JavaScript and npm package consumption in a large organization is typically managed by a repository manager. Commonly used repository manager applications are JFrog Artifactory, Sonatype Nexus Repository, and others. The repository manager acts as a single point of access for developers and development tools to retrieve the required libraries.
If your organization uses the upstream fallback
feature of Chainguard Repository, you can configure your repository manager
with a single upstream pointed at https://libraries.cgr.dev/javascript/. This
is the recommended setup. The Chainguard Repository handles fallback and policy
enforcement; your repository manager handles local caching and access control.
Chainguard also retrieves packages from the public npm Registry on your
behalf when upstream fallback is enabled. This includes protections such as
malware detection and a cooldown period for newly published
packages.
At a high level, adopting the use of Chainguard Libraries consists of the following steps:
https://libraries.cgr.dev/javascript/
as the single upstream source for JavaScript package retrieval. This can be done
either:Adopting the use of a repository manager is the recommended approach to minimize complexity. If your organization does not use a repository manager, refer to the direct access documentation for build tools.
Chainguard recommends using the Chainguard Repository’s built-in upstream fallback rather than configuring a public registry fallback in your repo manager. Configuring your own fallback bypasses the protection that the Chainguard Repository provides.
However, if upstream fallback is not enabled or you prefer to manage your own fallback
ordering, you can configure https://libraries.cgr.dev/javascript/ as a remote
repository alongside your npm upstream, and combine them in a virtual or group
repository with Chainguard as the first priority. The per-tool instructions on
this page follow this pattern.
If you are migrating an existing JavaScript project to Chainguard Libraries through a repository manager, your lockfile likely contains integrity hashes generated against packages previously downloaded from npm or through your repository manager. The chainctl libraries update-hashes command automates lockfile hash updates
for all supported JavaScript lockfile formats.
When you are using a repository manager, pass the full repository manager URL with --registry-url and authenticate with one of the supported methods: --username and --password, --token, or a .netrc entry for the registry host. For example:
chainctl libraries update-hashes \
--registry-url https://repo.example.com:8443/repository/javascript-all/ \
--token "$REPO_TOKEN"After updating the lockfile, keep your repository manager configuration in place and reinstall through the same repository manager endpoint to apply the updated hashes.
Learn more in the Build configuration page and in the chainctl docs.
Cloudsmith supports npm registries for proxying and hosting. Refer to the npm registry documentation and the npm Upstream documentation for Cloudsmith for more information. Cloudsmith supports combining repositories by defining multiple upstream repositories.
Use the following steps to configure a repository with the Chainguard Libraries for JavaScript repository as an upstream.
Configure a javascript-all repository. This repository acts as a single access point for JavaScript packages and may also include private packages or additional upstream sources, depending on your configuration.
Configure an upstream proxy for the Chainguard Libraries for JavaScript repository:
https://libraries.cgr.dev/javascript/If you are manually managing fallback, you can add an additional upstream
proxy for the public npm registry with a lower priority than
javascript-chainguard.
Use this setup for initial testing with Chainguard Libraries for JavaScript. For
production usage, add the javascript-chainguard upstream proxy to your production
repository.
The following steps allow you to determine the URL and authentication details for accessing the repository:
example organization is
https://npm.cloudsmith.io/example/javascript-all/.example organization is
//npm.cloudsmith.io/example/javascript-all/:_authToken=YOUR-API-KEYUse the provided code snippets directly for your use with npm, or adjust as necessary for other JavaScript build and packaging tools. Find relevant details in the Build Configuration and specific packaging tool documentation.
Use the following steps to retrieve the necessary API key as an authentication token for the registry access:
JFrog Artifactory supports npm repositories for proxying and hosting, and virtual repositories to combine them. Refer to the npm registry documentation for Artifactory for more information.
Use the following steps to add Chainguard Libraries for JavaScript as a remote repository:
Configure a remote repository for the Chainguard Libraries for JavaScript repository:
javascript-chainguard.https://libraries.cgr.dev/javascript/.Create a virtual repository, or add the remote repository to an existing virtual repository used for npm packages. A virtual repository may also include private npm packages or additional upstream sources, depending on your configuration.
javascript-chainguard.If you are manually managing fallback, you can configure an additional npm remote repository with lower priority.
Use this setup for initial testing with Chainguard Libraries for JavaScript. For
production usage add the javascript-chainguard repository to your production
virtual repository.
Chainguard Libraries uses Cloudflare R2 storage, meaning tarball downloads from
libraries.cgr.dev return a 302 redirect to a different host. Without
additional configuration, Artifactory may cache the redirect response instead of
the actual tarball, causing npm integrity checksum failures at install time.
To prevent this:
javascript-chainguard
remote repository, within in the Advanced tab:javascript-chainguard repository and click Zap Caches, then re-run your
install..tgz artifacts from
the remote cache, rather than deleting all, before re-running the install.After creating and configuring the javascript-chainguard remote repository, validate that Artifactory is successfully proxying through to Chainguard before proceeding. Because Artifactory falls back to the upstream npm registry when a connection to a remote repository fails, a misconfigured repository may silently resolve packages from npm rather than Chainguard — and the build will succeed without any visible error.
Common sources of misconfiguration include invalid or expired credentials, an incorrect or incomplete URL, and misconfigured settings in the Advanced tab. The Artifactory Test button on the repository configuration screen is not a reliable indicator; it may fail for a correctly configured repository, and may pass for an incorrectly configured one. Instead, use the following steps to verify that fetching an artifact through Artifactory produces the same checksum as fetching it directly from libraries.cgr.dev.
picocolors-1.1.1. You can substitute any artifact you know to be available.curl -sSf -L \
-u "${CHAINGUARD_JAVASCRIPT_IDENTITY_ID}:${CHAINGUARD_JAVASCRIPT_TOKEN}" \
https://libraries.cgr.dev/javascript/picocolors/-/picocolors-1.1.1.tgz \
| openssl dgst -sha512 -binary | base64curl -sSf -L \
-H "Authorization: Bearer ${ARTIFACTORY_TOKEN}" \
https://<artifactory-host>/artifactory/api/npm/javascript-chainguard/picocolors/-/picocolors-1.1.1.tgz \
| openssl dgst -sha512 -binary | base64Replace artifactory-host with your Artifactory instance hostname, and replace ${ARTIFACTORY_TOKEN} with your Artifactory identity token.
javascript-chainguard with a public npm fallback, test that as well:curl -sSf -L \
-H "Authorization: Bearer ${ARTIFACTORY_TOKEN}" \
https://<artifactory-host>/artifactory/api/npm/javascript-all/picocolors/-/picocolors-1.1.1.tgz \
| openssl dgst -sha512 -binary | base64The checksums returned by the commands must match.
If the checksum from the Artifactory remote or virtual repository differ from the direct fetch, or if the Artifactory fetch fails entirely, review the following before proceeding:
https://libraries.cgr.dev/javascript/.chainctl auth pull-token --repository=javascript and update the Artifactory repository credentials. Expired tokens fail silently.Do not proceed to virtual repository setup or build configuration until the checksums match.
The following steps allow you to determine the URL and authentication details for accessing the repository:
https://exampleorg.jfrog.io/artifactory/javascript-all/ with exampleorg
replaced with the name of your organization.Use the URL of the virtual repository in the build configuration and build a first test project. In a working setup the chainguard remote repository contains all libraries retrieved from Chainguard.
Sonatype Nexus Repository allows for merging multiple remote repositories as a repository group. The below instructions are based on the Nexus documentation for npm.
For initial testing and adoption it is advised to create a separate proxy repository for the Chainguard Libraries for JavaScript repository, and include it in a repository group:
Configure a proxy repository for the Chainguard Libraries for JavaScript repository:
https://libraries.cgr.dev/javascript/.Create a repository group, or add to an existing repository group:
javascript-chainguard to the right to include it in the group. Position
javascript-chainguard at the top of the list using the arrow controls.Repository groups can include multiple repositories, such as hosted repositories for private packages or additional proxy repositories. In a typical configuration, the Chainguard repository is placed first to ensure packages are retrieved through Chainguard when available.
If you are manually managing fallback, you can configure an additional npm proxy repository and add it to the group after javascript-chainguard.
The following steps allow you to determine the URL and authentication details for accessing the repository:
https://repo.example.com/repository/javascript-all/
with repo.example.com replaced with the hostname of your repository manager.Use the URL of the repository group, such as
https://repo.example.com/repository/javascript-all/ in the build
configuration and build a
first test project. In a working setup the javascript-chainguard proxy
repository contains all libraries retrieved from Chainguard.
Google Artifact Registry (GAR) is not an officially supported repository manager for Chainguard Libraries for JavaScript. However, it has been shown to work with the following configuration.
Configure two GAR remote repositories, with upstream validation disabled on the second:
javascript-chainguard pointing to https://libraries.cgr.dev/javascript with upstream validation enabledjavascript-chainguard-upstream pointing to https://libraries.cgr.dev/javascript-upstream with upstream validation disabled.When using artifactregistry-auth, note that it only injects credentials for repositories explicitly listed in your .npmrc. Ensure you add a credentials entry for the javascript-chainguard-upstream repository alongside your existing javascript-chainguard entry, otherwise you will receive 404s for upstream-fallback packages.
These instructions show how to mirror JavaScript packages from Chainguard Libraries into AWS CodeArtifact, then configure developers and CI systems to install packages from your private CodeArtifact repository.
If you use Chainguard Repository with upstream fallback enabled, npm clients can point directly to the Chainguard endpoint and retrieve either Chainguard-built packages or policy-protected upstream packages through that single registry. Use the CodeArtifact mirroring workflow only if your organization needs to keep AWS CodeArtifact as the registry your developers install from.
You will need the following:
jq, and bash. If you use pnpm lockfiles, you also need the Go mikefarah build of yq v4.This workflow supports both package-lock.json and pnpm-lock.yaml. For pnpm, the parser supports lockfile versions v5, v6, and v9. Scoped packages such as @types/node and @babel/core are also supported.
Note: This workflow preserves standard npm attestations embedded in tarballs, but Chainguard-specific registry metadata is not preserved in the mirrored repository. Because AWS CodeArtifact charges for storage and requests, you should monitor repository growth over time and clean up unused package versions as needed.
You can create the CodeArtifact resources manually with the AWS CLI:
export AWS_REGION="us-east-1"
aws codeartifact create-domain \
--domain npm-mirror-test \
--region $AWS_REGION
aws codeartifact create-repository \
--domain npm-mirror-test \
--repository cg-npm-packages \
--description "npm packages mirror from Chainguard" \
--region $AWS_REGIONAfter setup, export the values the mirroring workflow uses:
export AWS_REGION="us-east-1"
export CODEARTIFACT_DOMAIN="npm-mirror-test"
export CODEARTIFACT_REPOSITORY="cg-npm-packages"
export CGR_USER="your-chainguard-identity"
export CGR_TOKEN="your-chainguard-token"CODEARTIFACT_DOMAIN_OWNER is optional. If you do not set it, the workflow can use your current AWS account ID.
The mirroring workflow reads a project lockfile, extracts package names and versions, checks whether each version already exists in CodeArtifact, downloads missing packages from Chainguard Libraries, and publishes them into your private CodeArtifact repository.
Run the script against either an npm or pnpm lockfile:
./npm-codeartifact-mirror.sh ./package-lock.json./npm-codeartifact-mirror.sh ./pnpm-lock.yamlIf you do not pass a file path, the script automatically looks for package-lock.json and then pnpm-lock.yaml in the current directory.
The mirroring workflow runs in multiple passes. On the first pass, it skips versions that already exist in CodeArtifact and attempts to download and publish everything else. If a package is not yet available because Chainguard is still ingesting it from upstream, the workflow queues that package for a later retry.
By default, the workflow retries unavailable packages up to four times with a 30-second delay between passes. You can tune this behavior with INGEST_MAX_PASSES and INGEST_RETRY_DELAY.
For transient npm transport failures such as socket timeouts, rate limits, or 5xx responses, you can also tune NPM_FETCH_RETRIES and NPM_FETCH_TIMEOUT.
After the mirror completes, use the AWS CLI to verify that packages were published to CodeArtifact:
aws codeartifact list-packages \
--domain $CODEARTIFACT_DOMAIN \
--repository $CODEARTIFACT_REPOSITORY \
--format npm
aws codeartifact list-package-versions \
--domain $CODEARTIFACT_DOMAIN \
--repository $CODEARTIFACT_REPOSITORY \
--package lodash \
--format npmFor scoped packages, use the --namespace parameter:
aws codeartifact list-package-versions \
--domain $CODEARTIFACT_DOMAIN \
--repository $CODEARTIFACT_REPOSITORY \
--package fs-minipass \
--namespace isaacs \
--format npmIf any packages could not be mirrored, the workflow writes an unresolved package report. Each line includes the reason and package version, such as 404, ETARGET, or AUTH.
Once the packages are mirrored, authenticate to CodeArtifact and point npm at your repository endpoint:
export CODEARTIFACT_AUTH_TOKEN=$(aws codeartifact get-authorization-token \
--domain $CODEARTIFACT_DOMAIN \
--query authorizationToken \
--output text \
--region $AWS_REGION)
export CODEARTIFACT_REGISTRY=$(aws codeartifact get-repository-endpoint \
--domain $CODEARTIFACT_DOMAIN \
--repository $CODEARTIFACT_REPOSITORY \
--format npm \
--query repositoryEndpoint \
--output text \
--region $AWS_REGION)
npm config set registry $CODEARTIFACT_REGISTRY
npm config set //$(echo $CODEARTIFACT_REGISTRY | sed 's|https://||')/:_authToken $CODEARTIFACT_AUTH_TOKENYou can then install packages as usual:
npm installAs an alternative, you can use aws codeartifact login for npm:
aws codeartifact login \
--tool npm \
--domain $CODEARTIFACT_DOMAIN \
--repository $CODEARTIFACT_REPOSITORY \
--region $AWS_REGIONIf you cannot get a CodeArtifact authorization token or publish packages, verify your AWS credentials and IAM permissions. The workflow specifically relies on permissions such as codeartifact:PublishPackageVersion, codeartifact:PutPackageMetadata, codeartifact:GetAuthorizationToken, and codeartifact:GetRepositoryEndpoint.
CodeArtifact tokens expire after 12 hours. If authentication starts failing later, request a new token and retry.
If packages remain unavailable after all retry passes, Chainguard may still be ingesting them, they may be in a cooldown period, they may be blocked for security reasons, or the requested version may not exist. Re-running the workflow later, or increasing INGEST_MAX_PASSES and INGEST_RETRY_DELAY, can help pick up packages that were still within the ingestion window during an earlier run.
If you use pnpm and the workflow reports zero packages or fails because of yq, make sure you are using the Go mikefarah build of yq v4 rather than the Python kislyuk implementation.
Last updated: 2025-06-05 09:00