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
| Format | Language or Tool |
|---|---|
| npm | JavaScript and Node.js |
| Maven and Gradle | Java |
| PyPI | Python |
| NuGet | .NET and C# |
| Composer | PHP |
| Generic | Any 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
| Token | Best For |
|---|---|
| CI job token | Publishing from a pipeline |
| Personal access token | Publishing or installing from your own computer |
| Deploy token | Read-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
| Feature | Package Registry | Container Registry |
|---|---|---|
| Stores | Libraries and files | Docker images |
| Consumed by | Package managers such as npm and pip | Docker and Kubernetes |
| Typical content | Code your app imports | A 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.
