Open-source project
JuliaCI/PkgTemplates.jl avatar
JuliaCI/PkgTemplates.jl

PkgTemplates: repeatable Julia package scaffolding with plugins

Create new Julia packages, the easy way

703 stars112 forksJuliaMIT

At a glance

What is it?
PkgTemplates.jl is the Julia package generator that other packages build on, producing a project directory with git, GitHub Actions, Codecov and Documenter wiring from a declarative list of plugins. It is the layer above Pkg, and its limit is that it scaffolds a package rather than managing one.
Who is it for?
Adopt PkgTemplates.jl if you start several Julia packages, if your organisation has a house style for project files, or if you want continuous integration and documentation scaffolding to be reproducible rather than copy-pasted. Do not adopt it to manage an existing package, since it is a generator rather than a maintenance tool, and do not expect it to produce a registered package, since registration is a separate step you do yourself.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
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 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A generator for the parts of a package nobody enjoys writing

PkgTemplates creates new Julia packages in an easy, repeatable and customizable way. The word repeatable is the one that matters most, and it is the one that separates this from a shell script that copies a directory.

A Julia package is not only a src/ directory and a Project.toml. There is a test directory, a documentation site, a continuous integration configuration, a code coverage integration, a licence file, a git repository with the right remotes, and a set of conventions about how the package is registered and who is allowed to depend on it. Each of those is small, and collectively they are the part of starting a package that people usually get wrong or skip.

The tool is organised around a Template, which is a description of the package you want, and a plugin system, where each plugin contributes one of those pieces. The project is hosted under the JuliaCI organisation, which is the continuous integration organisation for the Julia ecosystem, and the repository carries a ColPrac contributor guide badge, meaning it follows the SciML collaborative practices guide for community packages. The code style is the Blue style, and there is a Codecov badge and a CI workflow on the master branch.

The scope is deliberately narrow. PkgTemplates is about the first minutes of a package's life. It is not a package manager, not a registry tool and not a way to keep an existing project in shape.

Installation through the Pkg REPL

PkgTemplates is installed with the Julia package manager, like any other registered Julia package. The README gives two equivalent forms, the first being the Pkg REPL mode:

julia
pkg> add PkgTemplates  # Press ']' to enter the Pkg REPL mode.

and the second being the programmatic call from a plain Julia session:

julia
julia> using Pkg; Pkg.add("PkgTemplates")

The comment in the first snippet is worth reading carefully, because it is a small usability trap: the pkg> prompt is the Pkg REPL, which you enter by pressing the closing bracket key, and pressing the opening bracket leaves it. A user who types the command into the ordinary julia> prompt will get an error rather than a package.

The two forms differ in what they are for. The REPL form is the interactive one, and the programmatic form is what you put in a script or a CI step. Since PkgTemplates is itself a Julia package, its users are the kind of people who script their environment, so the second form tends to matter more than it would for a library with a simpler setup.

The repository layout is small and tells you where the behaviour lives: src/ holds the implementation, templates/ holds the files that get copied into a generated package, test/ holds the test suite, docs/ holds the documentation source, and Project.toml is the package's own manifest.

Two ways to generate, and what the interactive one asks you

Generation happens in one of two ways. The interactive path is a single call:

julia
using PkgTemplates
Template(interactive=true)("MyPkg")

This prompts you to select options and displays the default settings in parentheses, so you see what you are accepting as you go. That parenthetical default display is a small but careful design choice: an interactive scaffolder that hides its defaults produces packages that nobody can reproduce later, because the person who ran it no longer remembers which option they left alone.

The manual path builds a Template in code:

julia
using PkgTemplates
tpl = Template()

and then generates the package from it:

julia
tpl("MyPkg")

The split matters because the second form is the one you can put in a script. A team that standardises on a template writes the template once as Julia code, keeps it in version control, and every new package is generated by calling it. That is the repeatable case, and it is the reason to prefer a Julia library over a directory of copied files: the template is code, so it can be reviewed, diffed and tested.

One assumption in the no-keywords constructor is worth knowing about. It assumes the existence of some preexisting Git configuration, shown with git config --list and set with git config --global. The configuration it expects is user.name for your real name, user.email for your email address, and github.user for your GitHub username.

Plugins are the real configuration surface

The plugin list is where the actual decisions live, and the README's example is the clearest illustration of what a customised template looks like:

julia
using PkgTemplates
tpl = Template(;
    dir="~/code",
    plugins=[
        Git(; manifest=true, ssh=true),
        GitHubActions(; x86=true),
        Codecov(),
        Documenter{GitHubActions}(),
    ],
)

Read that as four decisions rather than four features. The dir keyword sets where the package is written, so the template is not tied to the current working directory. The Git plugin sets up the repository, and its keywords choose whether a manifest file is tracked and whether the remote uses SSH rather than HTTPS. GitHubActions creates the continuous integration workflow, and x86 controls the architecture the workflow builds for. Codecov wires up coverage reporting. Documenter, parameterised by GitHubActions, sets up the documentation build so that it is driven by the same CI workflow rather than by a separate manual step.

That last parameterisation is the design idea worth taking away. Documenter is not a generic documentation plugin here, it is Documenter{GitHubActions}, bound to the CI plugin, so the docs are built when the workflow runs. Scaffolding that kind of relationship is more than a file copy, and it is the reason to spend time configuring plugins rather than copying a template directory by hand.

The parameterisation syntax, with a type parameter in braces, also means plugin behaviour is composed at the type level rather than at runtime, which keeps the generated output consistent with the types you asked for.

What the generated package does not get you

The most common misunderstanding about a scaffolding tool is what it leaves to you, and here the boundary is clear.

First, registration. A package generated by PkgTemplates is not a registered package. Registration is a separate step, a pull request against the General registry, and the general registry has its own contribution guidelines and its own review process. The generated project is a good candidate for that pull request, but the tool does not submit it for you.

Second, the CI workflow is a starting configuration, not a guarantee. The GitHubActions plugin with x86 enabled produces a workflow that runs on that architecture, and whether that matches your organisation depends on what you want to test. If you need several architectures, several Julia versions, a nightly build or a different runner, that is configuration work after generation.

Third, the documentation. The Documenter plugin with GitHubActions sets up the build, but a documentation site needs content, and usually a deployment target and a custom domain, none of which the template can know.

Fourth, and most important for a team, nothing keeps a package in shape after the first day. PkgTemplates is a one-shot generator. It does not re-run, it does not diff your package against the template, and it does not tell you that the template changed and your package has drifted. The drift problem is real for a template-heavy workflow, because the template is code that evolves while the generated packages sit still, and the manual work of noticing that the CI matrix gained a Julia version never gets automated.

The alternative is a directory you maintain yourself

The honest alternative is a directory of skeleton packages in version control, copied with a shell script when you start something new. The difference in approach is real and worth spelling out.

A copied directory is static. It is exactly what it was when you copied it, and when you improve it, the improvements apply to nothing until you manually propagate them. It also carries no information about intent, since a file in a template directory does not say why it is there or under what condition it should be included.

A Template is a program. The plugin list is a declaration of what you want, and the differences between two packages are visible as differences between two Template values. That means you can hold a default template in your own repository, review changes to it in a pull request, and generate every new package from the same source of truth. It also means the settings are typed, so a mistake in a keyword is an error at construction time rather than a missing file three months later.

There is a third option worth naming, and it is what some teams end up with: a shell script that runs PkgTemplates with an explicit plugin list, checked into the repository, used by a make target. That combines the declarative template with a simple entry point, and it is often the right shape for a small organisation.

The case against PkgTemplates is a matter of weight. It is a dependency with its own release cadence, its own documentation site and its own version of the Julia ecosystem, and for a project you will create once, that is more machinery than the problem needs. The break-even point is the second package.

Editorial conclusion

Adopt PkgTemplates.jl if you start several Julia packages, if your organisation has a house style for project files, or if you want continuous integration and documentation scaffolding to be reproducible rather than copy-pasted. Do not adopt it to manage an existing package, since it is a generator rather than a maintenance tool, and do not expect it to produce a registered package, since registration is a separate step you do yourself. Before you rely on it, read the user guide rather than only the README, decide which plugins you want in the default template rather than per package, and check the generated GitHub Actions workflow against the runners and Julia versions your organisation actually uses.

Frequently asked questions

What is PkgTemplates.jl?

It is a Julia package that creates new Julia packages in an easy, repeatable and customizable way, using a Template object and a list of plugins. It is developed under the JuliaCI organisation, is MIT licensed, and its documentation is published as a user guide and a developer guide.

How do I install PkgTemplates?

Install it with the Julia package manager, either in the Pkg REPL with pkg> add PkgTemplates, where you enter that mode by pressing the closing bracket key, or programmatically with julia> using Pkg; Pkg.add("PkgTemplates").

What are the available plugins for PkgTemplates?

The README example shows Git with manifest and ssh options, GitHubActions with an x86 option, Codecov, and Documenter parameterised by GitHubActions. The Template constructor also takes a dir keyword that sets where the generated package is written.

Does PkgTemplates register the package it generates?

The documentation describes generating a new package directory, and registration is a separate step that you perform against the General registry yourself. The generated project is prepared for that pull request, but the tool does not submit it.

Is PkgTemplates.jl still maintained?

The repository is not archived and the last push was on 2026-10-20. Recent releases are v0.7.63 from 2026-08-01, v0.7.62 from 2026-05-18 and v0.7.61 from 2026-03-18, and the project is MIT licensed with a Blue code style.

Official sources

  1. JuliaCI/PkgTemplates.jl on GitHub
  2. License: MIT
  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/juliaci-pkgtemplates-jl.svg)](https://hysenlabs.com/projects/juliaci-pkgtemplates-jl)

Was this useful?