GitLab Package Registry

The GitLab Package Registry stores software packages inside your project. Developers publish a library once, and other projects install it by name and version. Teams skip the work of running a separate package server.

Think of a company warehouse. Each team stores finished parts on labeled shelves. Other teams collect the parts they need and never rebuild them.

How a Package Moves

  Library project                          App project
  ┌────────────────┐                      ┌────────────────┐
  │ Write code     │                      │ npm install    │
  │ Push to main   │                      │ @acme/utils    │
  └───────┬────────┘                      └────────▲───────┘
          ▼                                        │
  ┌────────────────┐   publish    ┌────────────────┴───────┐
  │ Pipeline job   ├─────────────►│  GitLab Package        │
  │ npm publish    │              │  Registry              │
  └────────────────┘              │  @acme/utils  1.0.0    │
                                  └────────────────────────┘

Supported Package Types

FormatLanguage or Tool
npmJavaScript and Node.js
Maven and GradleJava
PyPIPython
NuGet.NET and C#
ComposerPHP
GenericAny file type

Find the Registry

Open your project and select Deploy → Package Registry. The page lists every published package with its version, size, and upload date.

Authentication Choices

TokenBest For
CI job tokenPublishing from a pipeline
Personal access tokenPublishing or installing from your own computer
Deploy tokenRead-only installs on servers

Create personal and deploy tokens with the smallest permission set that works. Tokens for the registry need the read_api or write_registry scope, depending on the task.

Publish an npm Package

Set Up package.json

Name the package with a scope that matches your group name.

{
  "name": "@acme/utils",
  "version": "1.0.0",
  "description": "Shared helper functions"
}

Add an .npmrc File

Replace 1234 with your project ID, found under Settings → General.

@acme:registry=https://gitlab.com/api/v4/projects/1234/packages/npm/
//gitlab.com/api/v4/projects/1234/packages/npm/:_authToken=${CI_JOB_TOKEN}

Publish from a Pipeline

publish-package:
  stage: deploy
  image: node:20
  script:
    - npm publish
  rules:
    - if: $CI_COMMIT_TAG

The job runs when someone pushes a version tag. A package version cannot be overwritten, so each tag needs a fresh number in package.json.

Install an npm Package

The consuming project needs the same registry line in its own .npmrc file.

@acme:registry=https://gitlab.com/api/v4/projects/1234/packages/npm/
npm install @acme/utils

Publish a Generic Package

The generic type accepts any file. Installers, data files, and compiled tools all fit.

upload-file:
  stage: deploy
  script:
    - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file build/app.zip "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/my-app/1.0.0/app.zip"'

The address follows a pattern: package name, version, and file name.

Download a Generic Package

curl --header "PRIVATE-TOKEN: <your_token>" --output app.zip "https://gitlab.com/api/v4/projects/1234/packages/generic/my-app/1.0.0/app.zip"

Manage Published Packages

  • Open a package entry to read its install command and file list.
  • Delete outdated versions to save storage.
  • Set a cleanup policy under Settings → Packages and registries to remove old files on a schedule.
  • Keep package access aligned with project visibility so that private code stays private.

Package Registry and Container Registry

FeaturePackage RegistryContainer Registry
StoresLibraries and filesDocker images
Consumed byPackage managers such as npm and pipDocker and Kubernetes
Typical contentCode your app importsA complete runnable app

Control Storage Costs

Every published version consumes storage. A library released weekly for two years leaves more than one hundred versions behind. Review the registry each quarter, keep the versions that active projects use, and delete the rest. Cleanup policies automate this routine and keep the registry tidy for new developers who browse it.

Good Habits

  • Follow semantic versioning for every package.
  • Publish only from the pipeline, never from personal computers.
  • Scan packages for known weaknesses before release.
  • Write a README that shows install and usage steps.