# RFC: REUSE compliance plugin for PkgTemplates.jl — API, docs, and root LICENSE behavior

**URL:** https://discourse.julialang.org/t/rfc-reuse-compliance-plugin-for-pkgtemplates-jl-api-docs-and-root-license-behavior/136981
**Category:** Package Management
**Tags:** pkg, licenses, pkgtemplates
**Created:** [May 4, 2026, 2:56pm UTC](https://discourse.julialang.org/t/rfc-reuse-compliance-plugin-for-pkgtemplates-jl-api-docs-and-root-license-behavior/136981 "2026-05-04T14:56:52Z")
**Posts on this page:** 4
**Page:** 3

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [May 5, 2026, 7:45pm UTC](https://discourse.julialang.org/t/rfc-reuse-compliance-plugin-for-pkgtemplates-jl-api-docs-and-root-license-behavior/136981/42 "2026-05-05T19:45:59Z")

</div>

> [@goerz](#):
>
> As long as that license also matches the fine-grained license for (approximately all of) the _code_, and as long as the fine-grained licenses for non-code aren’t _surprising_, I don’t think that’s too much of a problem.

Yeah, that’s really the crux of it. I’m all for reasonable, but your value of “surprising” may be different than mine or Acme Inc’s legal staff or Globex Corp’s internal SBOM audit. If I see prominent labels like this on a repository, I might not go looking any farther:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/6/0/60152397c95e0c64a4299d301356af4e51c3c9ac.png) ![image](https://global.discourse-cdn.com/julialang/original/3X/2/5/25216aac3a947fec9c2ddc9ec5d6b2f5edac427c.png)

That’s what I’d think the GitHub “repository license” notice is.

That said, I do think we need to find ways to do better here. I’d love to similarly expose better mixed licensing information for packages with artifacts (like JLLs). There it’s typically _far_ more surprising.

> [@goerz](#):
>
> At the end of the day, though, right now there is no way _not_ to have a main `LICENSE` file for registered packages. So we have to work around that fact in some sensible way

This just seems like a very bad rationale — that requirement is there to ensure folks know how to responsibly use a package. If it’s not accurate or representative, then it becomes less useful.

---

<div class="post-metadata">

### Author: ![gwr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gwr/32/33632_2.png) [@gwr](https://discourse.julialang.org/u/gwr)
#### Post date: [May 5, 2026, 9:05pm UTC](https://discourse.julialang.org/t/rfc-reuse-compliance-plugin-for-pkgtemplates-jl-api-docs-and-root-license-behavior/136981/43 "2026-05-05T21:05:40Z")

</div>

I think I now see the tension more clearly.

There are two valid but different concerns here:

1. For current Julia tooling and General registration, a conventional root `LICENSE` file is useful, and probably expected for the ordinary package case.

2. At the same time, a root `LICENSE` file should not silently imply that the whole repository is under one license when the generated REUSE metadata assigns different licenses to different parts of the repository.

So I think the safest default for a PkgTemplates plugin is probably the boring  
happy path:

- generate a conventional root `LICENSE`;
- make the default generated layout uniformly licensed;
- add the corresponding REUSE metadata from the start.

In other words, `Reuse()` should probably generate a registry-friendly package  
where the root `LICENSE` and the REUSE metadata tell the same licensing story.

More elaborate REUSE setups should remain possible, for example different  
licenses for code, docs, assets, or generated artifacts. But once the user chooses  
such a non-uniform setup, the plugin should avoid pretending that a single root  
license describes the whole repository. In that case, the authoritative licensing  
information should be the SPDX headers, `REUSE.toml`, and `LICENSES/`; a root  
`LICENSE` should either be omitted or generated only by explicit user choice (actually I am not for it).

That would make the default simple and compatible, while still allowing REUSE to  
do what it is meant to do for more detailed file-level licensing.

Note that this is possible, because if only `license` is filled all other license expressions will default to that unless divergent expressions are given.

---

<div class="post-metadata">

### Author: ![gwr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gwr/32/33632_2.png) [@gwr](https://discourse.julialang.org/u/gwr)
#### Post date: [May 6, 2026, 10:54am UTC](https://discourse.julialang.org/t/rfc-reuse-compliance-plugin-for-pkgtemplates-jl-api-docs-and-root-license-behavior/136981/44 "2026-05-06T10:54:51Z")

</div>

Thanks to all participants here for their help. By now, I am fairly clear about how to proceed.

### Additional Switches

The REUSE plugin needs two additional switches. The fine-tuning is a bit different from what I had originally expected:

```Julia
root_license::Bool = true
license_approval::String = "code" # "strict" | "code" | "none"

```

#### Root License

If `root_license=true` — the default — then one of the following will happen:

- If there is a single plain license for all files in the project, i.e. no `WITH` exception and effectively `license == artifact_license == docs_license == docs_asset_license`, then that license text is copied from `LICENSES/` to the root directory as `LICENSE`.
- In all other cases, `LICENSE` is written as a simple text file pointing to the REUSE layout, i.e. to SPDX file headers, `REUSE.toml`, and `LICENSES/`. This avoids pretending that a multi-license project has one single root license text.

#### License Approval Checking

`license_approval` controls optional checks against license approval metadata. The default is `"code"`, which should match the usual expectations for Julia packages intended for General.

Invalid values should throw an error. They should not silently fall back to `"none"`.

The behavior should be:

- `license_approval="code"` requires that the primary code `license` expression has an OSI-approved path according to the bundled SPDX License List metadata. For example, `MIT OR LicenseRef-X` passes because the expression provides an OSI-approved path. `WITH` exceptions are rejected here for now, as a conservative interpretation.

- `license_approval="strict"` includes the requirements of `"code"` and additionally requires all other license expressions to have either an OSI-approved or FSF-libre path according to the bundled SPDX metadata. For example, `CC-BY-NC-4.0` would fail.

- `license_approval="none"` disables OSI/FSF-libre approval checks and allows the broadest REUSE-compliant setup, including custom `LicenseRef-*` licenses and license exceptions.

A failed approval check does not mean that a license is invalid, non-free, or unsuitable. It only means that the requested approval property cannot be verified from the bundled metadata.

In my view, this is the most honest compromise: it nudges users toward the simple happy path and makes REUSE-compliant setup easy, while still allowing the full REUSE/SPDX model where users explicitly ask for it.

### Examples

#### Hello REUSE

```Julia
Template(;
    plugins=[
        !License,
        Reuse(),
    ],
)

```

This sets up the package with everything under the `"MIT"` license. A copy of that license text will be available as `LICENSES/MIT.txt` and, because this is a single-license setup, also as root `LICENSE`.

`REUSE.toml` is written and SPDX file headers are added to files in `src/`, `test/`, and `benchmark/`, for example. A `## Licensing`section is added to `README.md`, naming `MIT` as the license for the code and pointing out that the project follows REUSE.

#### General registry ready

```Julia
Template(;
    plugins=[
        !License,
        GitHubActions(),
        Reuse(;
            license = "EUPL-1.2+"
        ),
    ],
)

```

This is similar to the previous example, but here the primary code license is `EUPL-1.2+`, a valid SPDX 2.3 license expression using the `+` operator for “or later”. The generated project will contain `LICENSES/EUPL-1.2.txt`, and that text is copied to root `LICENSE`.

Additionally, `reuse lint` is added to the GitHub Actions workflow.

#### Free-play

```Julia
Template(;
    plugins=[
        !License,
        GitHubActions(),
        Reuse(;
            license = "GPL-3.0-or-later",
            artifact_license = "CC0-1.0",
            docs_license = "CC-BY-SA-4.0",
            license_approval = "strict"
        ),
    ],
)

```

This is similar to `General registry ready`, but now different license expressions are used. Code is licensed under `GPL-3.0-or-later`, artifacts under `CC0-1.0`, and documentation — including assets — under `CC-BY-SA-4.0`.

Since this is no longer a single-license setup, the root `LICENSE` file becomes a pointer to the REUSE layout instead of duplicating one license text.

With `license_approval="strict"`, non-code license domains are also checked against approval/libre metadata. For example, a non-commercial documentation license such as `CC-BY-NC-4.0` would fail this check.

---

<div class="post-metadata">

### Author: ![gwr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gwr/32/33632_2.png) [@gwr](https://discourse.julialang.org/u/gwr)
#### Post date: [May 7, 2026, 3:44pm UTC](https://discourse.julialang.org/t/rfc-reuse-compliance-plugin-for-pkgtemplates-jl-api-docs-and-root-license-behavior/136981/45 "2026-05-07T15:44:50Z")

</div>

**Update:**  
~~The PR has now been updated with the discussed changes in place.  
An updated documentation-preview is also available.~~

~~Feedback is very welcome.~~

I am closing this PR for now.

The SPDX parsing, expression normalization, SPDX license-list handling, license-text checks, and REUSE policy logic have become more general-purpose than I originally intended for this PkgTemplates.jl plugin.

I think the better architecture is to move that functionality into a separate package, with its own API, tests, documentation, governance, and release process. A future PkgTemplates.jl integration can then be a much thinner layer focused only on project generation.

Thanks for the review and discussion so far.  
Stay tuned for REUSE support!

[Previous page](https://discourse.julialang.org/t/rfc-reuse-compliance-plugin-for-pkgtemplates-jl-api-docs-and-root-license-behavior/136981.md?page=2)
