Why offer one codebase under several licenses
A copyright holder can license the same code under multiple sets of terms at once. Recipients simply choose one and follow its terms. There are two main reasons to do this.
- Broader compatibility — to fit well with different ecosystems at the same time.
- Business model — to publish as open source while selling a separate commercial license.
Type 1: two permissive licenses together — MIT OR Apache-2.0
This is the approach used by the Rust language and most Rust crates. Users choose whichever of MIT or Apache-2.0 suits them.
- Choosing Apache-2.0 gives you an express patent grant.
- Choosing MIT lets you include it in GPL-2.0-only projects too (because of the FSF's position that Apache-2.0 is incompatible with GPL-2.0).
You get both advantages, which makes it popular with library authors. By convention the repository contains two files, LICENSE-MIT and LICENSE-APACHE.
Type 2: copyleft + commercial — "GPL, or pay"
The code is released under the GPL or AGPL, and companies that do not want the source disclosure obligation can buy a commercial license under a separate contract. MySQL (GPL + Oracle commercial license) and Qt (LGPL-3.0/GPL + commercial) are well-known examples.
This model only works if the copyright holder holds the rights to all of the code. The copyright holder has no right to sell code contributed by outsiders only under the GPL under a commercial license.
CLA and DCO
- CLA (Contributor License Agreement): An agreement in which contributors give the project's steward broad rights (including relicensing) to use their contributions, or assign their copyright. It is practically required for commercial dual licensing. Some forms, like the Apache Foundation's ICLA, grant only relicensing rights and leave copyright with the contributor.
- DCO (Developer Certificate of Origin): Contributors confirm with each commit that "I have the right to submit this code under this project's license" (
git commit -sadds aSigned-off-by:line). The Linux kernel uses it. A DCO does not grant relicensing rights, so it is insufficient for commercial dual licensing.
Writing it as an SPDX expression
The relationship between multiple licenses is written as an SPDX license expression.
| Expression | Meaning | Example |
|---|---|---|
A OR B | Choose and follow one of the two (elective dual) | MIT OR Apache-2.0 |
A AND B | Both must be followed (different parts mixed together) | MIT AND BSD-3-Clause |
A WITH exception | Attach an exception to a license | GPL-2.0-only WITH Linux-syscall-note |
| Parentheses | Set the order of evaluation | (MIT OR Apache-2.0) AND Unicode-3.0 |
Confusing OR and AND reverses the meaning. If users can choose, it is OR; if all must be followed, it is AND.
Things to watch out for
- Rights already granted remain: Even if you later offer only a commercial license, the permissions for versions previously released as open source generally remain valid.
- It is not "open core": A model where the core is open source and extra features are sold as proprietary is not dual licensing. Dual licensing means offering the same code under two licenses.
- Don't confuse it with source-available licenses: More and more projects are switching to licenses like the BUSL or SSPL, whose source is visible but which are not open source by the OSI definition. That is a different strategy from dual licensing.
- Get the notice files right: For an elective dual license, provide the full text of each license and state clearly in the README that users may choose either.
Example
To apply Rust-style dual licensing, download the MIT and Apache-2.0 files from the generator, save them as LICENSE-MIT and LICENSE-APACHE, and write license = "MIT OR Apache-2.0" in your metadata. In each file header, write SPDX-License-Identifier: MIT OR Apache-2.0.
This article is general information, not legal advice. Consult a professional for important decisions.
Sources
- SPDX Specification, License Expressions — https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/
- Rust API Guidelines, Licensing — https://rust-lang.github.io/api-guidelines/necessities.html
- Developer Certificate of Origin — https://developercertificate.org/
- Apache ICLA — https://www.apache.org/licenses/contributor-agreements.html