Library / SDK
JuliaLang/Pkg.jl avatar
JuliaLang/Pkg.jl

Pkg.jl is the package manager Julia ships in the box

Pkg - Package manager for the Julia programming language

677 stars304 forksJuliaNOASSERTION

At a glance

What is it?
Pkg.jl is Julia's package manager, developed in its own repository and shipped with every Julia release from 1.0 onward, with a registry model, a project environment, and a documented development workflow. It suits Julia users who need reproducible environments, and it is the wrong place to look for a package manager you can point at another language's ecosystem.
Who is it for?
Pkg.jl is the right tool for anyone building in Julia, because it is the environment model the language's own tooling assumes, and the project and manifest pair it maintains is the only reproducible description of a Julia dependency set. It is the wrong tool if you need to consume a Julia package from a non-Julia runtime, or if you want a package manager that resolves across several language ecosystems, since the registry and the resolver are Julia specific.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Julia, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A stdlib with its own repository and its own release tags

Pkg.jl is unusual in a way that matters for anyone reasoning about it. It is the package manager for the Julia programming language, and it is developed in the JuliaLang organisation as its own project rather than inside the Julia monorepo, with a master branch, a changelog and tagged releases of its own. At the same time it is shipped with Julia v1.0 and above, which means it is not something you install separately on a normal machine, it is the resolver and environment manager already sitting inside your Julia installation. The repository layout reflects a standard library package rather than a standalone application. There is a Project.toml at the root, the source in src/, tests in test/, documentation in docs/, extensions in ext/, and a vendor directory. The default branch is master, and the licence is the one the Julia ecosystem uses for its standard libraries, held in a LICENSE.md file rather than a file GitHub can classify, which is worth checking if you intend to vendor code from it. The documentation is published at pkgdocs.julialang.org with separate builds for the release branch and for development.

Working on Pkg itself means running Julia against the checkout

The development instructions are concrete, and they are the clearest statement of how tightly Pkg is bound to the Julia runtime. The documented sequence is to fork and clone the repository, then change into the cloned directory and start Julia with the project flag, at which point importing Pkg loads the files from the checkout instead of the Pkg standard library:

bash
julia --project

Importing Pkg inside that session is what triggers the substitution, and running the test suite is a function call rather than a shell command:

bash
import Pkg
Pkg.test()

That substitution behaviour is the point. There is no way to run a different package manager against a Julia project, because Pkg is the API the ecosystem talks to. The same coupling shows up in how a Julia build picks up a Git checkout of Pkg. Instead of the normal build, you use make DEPS_GIT=Pkg when building Julia from source, the Pkg repository is expected to live in stdlib/Pkg, and that directory is created initially with a detached HEAD. If you are working from a pre-existing Julia repository you may need make clean beforehand, because stale build artefacts survive the switch. The repository also points at the Julia devdocs for the case of checking out two or more standard libraries at once, which is the situation where the detached HEAD arrangement becomes awkward.

Pre-commit hooks that format and validate before a commit lands

The repository uses pre-commit hooks, and the readme lists what they actually check, which is more informative than a generic claim about CI. The checks cover file size and case conflict validation, YAML syntax checking, trailing whitespace removal and line ending fixes, and Julia code formatting with Runic. That last item matters most for a code base that is also a standard library, since formatting differences between a contributor's editor and the project style are the kind of noise that turns a large pull request into a review problem. Installing the hooks takes three steps, and all three are ordinary shell commands:

bash
pip install pre-commit
pre-commit install
pre-commit run --all-files

The first installs pre-commit itself, the second registers the hooks with git in the repository root, and the third runs the full set across every file rather than only the ones about to be committed. Once installed the hooks run automatically on each commit, and pre-commit run on its own executes them manually at any time. The configuration lives in a .pre-commit-config.yaml file at the root, so the check set is declarative and reviewable, and the repository also carries a .git-blame-ignore-revs file, which is the conventional way to keep formatting-only commits from polluting git blame for a project like this.

How Pkg reaches the Julia distribution

Because Pkg lives outside the Julia repository but ships inside it, there is a synchronisation step, and the readme documents it with a pointer to a single file that holds the answer. To see which commit the Julia master branch uses, look at JuliaLang/julia/stdlib/Pkg.version in the Julia repository. That file is the coupling point between two repositories with independent commit histories. The recommended way to open a pull request that updates it is the JuliaPackaging/BumpStdlibs.jl GitHub Actions bot, which means a stdlib bump is normally an automated pull request rather than a hand edited version file. This arrangement has a practical consequence for anyone pinning versions. The version of Pkg that a given Julia release ships is decided in the Julia repository, not in the Pkg repository, so the Pkg release tags and the Pkg version inside a Julia installation are two different numbers. When auditing a build, the file to check is stdlib/Pkg.version in the Julia checkout, not the latest tag in this repository.

Continuous integration and coverage wired for a standard library

The project runs its own CI, and the badges at the top of the readme point at the details rather than a marketing page. The build status badge links to the actions page filtered on a workflow named Run tests, and there is a separate codecov badge tracking coverage on the master branch. The configuration lives in a .codecov.yml file at the root, and a .gitattributes file is present for line ending handling, which pairs with the whitespace normalisation the pre-commit hooks perform. The CI badge is worth reading carefully for anyone who wants to judge the state of the project, because a standard library that ships with a language release has a stricter correctness bar than an ordinary package, and the readme's split between the release documentation build at pkgdocs.julialang.org/v1/ and the development build at /dev/ mirrors that bar. One detail in the readme is easy to miss: the note that the hooks format code with Runic, which is a formatter choice specific to this project and is why contributors should install the hooks rather than trust their editor settings.

What Pkg does not do, and where the boundary sits

The readme for this repository is a development readme, not a user manual, and that shape tells you where the limits of the documentation are. It covers working on Pkg, the pre-commit hooks and the stdlib synchronisation. It does not cover how a user adds a package, how the registry is structured, how conflicts are resolved, or how to vendor a dependency that is not registered, because those topics live in the separate user documentation site rather than here. If you are evaluating Pkg as a package manager, you should read the user documentation for the behaviour and this repository for the maintenance picture, and the two answer different questions. The same gap shows up in the alternatives. There is no second package manager for Julia that the readme points to, and there is no support for using a non-Julia package manager to install Julia packages, because the resolver, the registry and the Project.toml environment are one integrated design. A team that needs a single dependency tool across a polyglot repository should not expect Pkg to cover the other languages, and a team that needs to pin a Julia dependency from a shell script inside a larger build system is looking at the wrong layer.

Editorial conclusion

Pkg.jl is the right tool for anyone building in Julia, because it is the environment model the language's own tooling assumes, and the project and manifest pair it maintains is the only reproducible description of a Julia dependency set. It is the wrong tool if you need to consume a Julia package from a non-Julia runtime, or if you want a package manager that resolves across several language ecosystems, since the registry and the resolver are Julia specific. Verify first that your Julia version matches the Pkg release you pin, that the environment file you commit reflects the same Julia version as CI, and that the stdlib sync noted in the last push is not about to change the version you depend on. The last push was on 2026-10-20 and the newest release is v1.13.1 from 2026-09-29.

Frequently asked questions

Do I need to install Pkg.jl separately in Julia?

No. Pkg is shipped with Julia v1.0 and above, so it is already part of a normal Julia installation. This repository is the development home for it rather than a separate distribution channel.

How do I test a change to Pkg.jl?

Start Julia with julia --project from the cloned repository, then import Pkg so the checkout is loaded instead of the standard library, and call Pkg.test() to run the suite.

What pre-commit checks does the Pkg.jl repository run?

File size and case conflict validation, YAML syntax checking, trailing whitespace removal and line ending fixes, and Julia code formatting with Runic. Install them with pre-commit install from the repository root.

How do I find out which version of Pkg my Julia uses?

Check the Pkg.version file at stdlib/Pkg.version in the JuliaLang/julia repository, which records the commit that Julia master uses. The readme recommends opening the update pull request through the JuliaPackaging/BumpStdlibs.jl bot.

Can I use Pkg.jl to manage dependencies for a non-Julia project?

No. The resolver, the registry and the Project.toml environment are specific to Julia, and importing Pkg inside Julia with the project flag is what makes a checkout take precedence over the shipped standard library. The readme points to no alternative package manager for other languages.

Official sources

  1. Issues
  2. JuliaLang/Pkg.jl on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/julialang-pkg-jl.svg)](https://hysenlabs.com/projects/julialang-pkg-jl)

Was this useful?