# Copyleft License

> A copyleft license lets anyone use, modify, and share code, on the condition that distributed copies and derivatives keep the same license and source.

Also known as: Reciprocal license, Share-alike license, Strong copyleft, Weak copyleft, Network copyleft

Source: https://socket.dev/glossary/copyleft-license

Last updated: 2026-10-24

A copyleft license (also called a reciprocal or share-alike license) lets anyone use, modify, and redistribute code on one condition: whoever distributes the code, or a work built from it, must pass on the same license and the source. That condition keeps derivatives open, and it decides what GPL, LGPL, MPL, and AGPL dependencies cost you to ship.

The most important fact about a copyleft license is that it attaches to distribution, not to contact. Running, modifying, or linking copyleft code inside your own organization triggers nothing. Shipping it to someone else does, and the AGPL adds network use. In October 2026, we installed a default [create-next-app](https://nextjs.org/docs/app/api-reference/cli/create-next-app) project with Next.js 16.4.3: 4 of its 358 packages declare copyleft licenses, none of them listed in the project's package.json. The one in the production tree is a single native binary that declares one license and contains nine copyleft libraries. Our position: blanket "no copyleft" policies are both noisy and blind. Policy should key on the copyleft tier and on how the code leaves your hands, and it should be checked against what is inside each package, not the license string in its metadata.

## What is a copyleft license?

A copyleft license is a copyright license that grants broad permissions and attaches a reciprocity condition to redistribution. To see why that design exists, start with the default. Copyright gives the author exclusive rights to copy, modify, and distribute a work the moment it is written. Without a license, a user has none of those rights.

A [permissive license](https://socket.dev/glossary/permissive-license) such as MIT grants those rights with almost no strings. The [MIT License](https://socket.dev/glossary/mit-license) asks for one thing: "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software." Anyone may take MIT code, change it, and ship the result as closed-source software.

Copyleft was designed to close that path. The Free Software Foundation (FSF) explains that placing a program in the public domain lets "uncooperative people" convert it into proprietary software. A copyleft license uses copyright to prevent that conversion instead. The FSF's [own definition](https://www.gnu.org/licenses/copyleft.html) is one sentence:

```text
Copyleft says that anyone who redistributes the software, with or without changes, must pass along the freedom to further copy and change it.
```

The mechanism is a condition on a permission. The GPL grants you the right to copy and distribute the code only if you meet its terms when you do. Break the terms and you lose the permission, which leaves you distributing someone else's code without a license. That is why copyleft is enforceable at all: the backstop is ordinary copyright infringement, not a novel legal theory.

The trigger matters more than any other detail. [GPLv3](https://www.gnu.org/licenses/gpl-3.0.html), published on June 29, 2007, calls distribution "conveying" and says in Section 2: "You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force." [GPLv2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html), from June 1991, uses the word "distribute" to the same effect. Private use, internal modification, and running a server are not distribution. A pejorative name for copyleft, "viral license," gets this backwards. Copyleft code does not infect anything it touches. It imposes duties on the person who ships it.

## What is the difference between strong and weak copyleft?

The difference between strong and weak copyleft is how much code the sharing condition reaches when you distribute. Weak copyleft reaches only the licensed component and your changes to it. Strong copyleft reaches the whole program built with it. Network copyleft extends strong copyleft's trigger to users who interact with the software over a network.

The [Blue Oak Council's copyleft guide](https://blueoakcouncil.org/copyleft) sorts licenses into four families: weak, strong, network, and maximal. Each family draws its boundary with different machinery.

The [Mozilla Public License (MPL) 2.0](https://www.mozilla.org/en-US/MPL/2.0/) draws it at the file. Section 1.10 defines a covered modification as "any file in Source Code Form that results from an addition to, deletion from, or modification of the contents of Covered Software." Edit an MPL file and that file stays MPL. Add a new file of your own and it does not. Section 3.3 lets you distribute the combined "Larger Work" under terms of your choice.

The GNU Lesser General Public License (LGPL) draws it at the library. You can ship a proprietary application that uses an LGPL library, but you must not prevent users from replacing the library with a modified version. LGPLv3 Section 4(d) offers two ways to meet that duty. The common one is to "use a suitable shared library mechanism for linking with the Library," meaning dynamic linking against a copy the user can swap.

The GNU General Public License (GPL) draws it at the program. GPLv3 Section 5(c) requires you to "license the entire work, as a whole, under this License" when you convey a modified version. If your code and a GPL library form one program, the program ships under the GPL with complete source. The GPL's main structural exception is the aggregate: separate programs that merely sit on the same distribution medium, such as two binaries in one container image, do not pull each other in.

The [AGPL license](https://socket.dev/glossary/agpl) keeps the GPL's boundary and adds a second trigger. Its Section 13 requires you to offer source to users who interact with a modified version over a network, even when no copy ever leaves your servers.

> Nothing in any panel applies until you distribute the program, except the AGPL network trigger. Private use and modification carry no copyleft obligation.
>
> Four panels show the same distributed program: your code files plus one copyleft component. Under MPL-2.0, only the MPL-covered files must stay open. Under the LGPL, the library must stay open and your app must allow relinking with a modified library, but your source stays closed. Under the GPL, the whole program must be released under the GPL with source. Under the AGPL, the whole program must be released, and the trigger also includes users who reach a modified version over a network.

The figure compares the same distributed program, made of your code plus one copyleft component, under four licenses. Under MPL-2.0, only the MPL-covered files, including your edits to them, must be released as source; new files you add stay under your terms. Under the LGPL, the library's source must be released and your application must permit relinking with a modified library, but your application's source stays closed. Under the GPL, the whole combined work must be released under the GPL with complete source. Under the AGPL, the same is true, and the obligation is also triggered by remote users of a modified version. Except for that AGPL network trigger, nothing applies until you distribute the program.

| Family | What must stay open | Trigger | Can a proprietary program include it? | Common SPDX identifiers |
| --- | --- | --- | --- | --- |
| Weak, file-level | The licensed files and your edits to them | Distribution | Yes | MPL-2.0, CDDL-1.0 |
| Weak, library-level | The library; users must be able to relink | Distribution | Yes, with replaceable linking | LGPL-2.1-or-later, LGPL-3.0-or-later |
| Strong | The entire combined program | Distribution | No, except as a separate program in an aggregate | GPL-2.0-only, GPL-3.0-or-later |
| Network | The entire combined program | Distribution, or network use of a modified version | No | AGPL-3.0-only, AGPL-3.0-or-later |

Licenses also carry exceptions that move these boundaries. The [Classpath exception](https://spdx.org/licenses/Classpath-exception-2.0.html) lets you link a GPL library "with independent modules to produce an executable, regardless of the license terms of these independent modules." [SPDX](https://socket.dev/glossary/spdx) expresses an exception with the WITH operator, as in GPL-2.0-only WITH Classpath-exception-2.0. A license string with WITH in it is a different set of terms from the bare license, and a policy engine should treat it that way.

## Is the MIT license copyleft?

The MIT license is not copyleft. MIT is a permissive license: its only condition is that you keep the copyright and permission notice. You owe no source code, and you may relicense your modifications however you like.

Permissive and copyleft code combine in one direction only. MIT, ISC, and 2- and 3-clause BSD code can go into a GPL program, because the GPL's terms satisfy their notice conditions. GPL code cannot go into an MIT-licensed program, because shipping it under MIT would drop the GPL's conditions. The [Apache License 2.0](https://socket.dev/glossary/apache-license-2-0) shows that compatibility is a property of specific license versions. The Apache Software Foundation [states](https://www.apache.org/licenses/GPL-compatibility.html) that Apache 2.0 code can go into GPLv3 projects, but "the FSF has never considered the Apache License to be compatible with GPL version 2."

Some widely used npm packages offer both kinds of license at once. The npm registry records jszip as (MIT OR GPL-3.0-or-later) and node-forge as (BSD-3-Clause OR GPL-2.0). OR means the recipient picks one. A team that takes jszip under MIT has no copyleft obligation at all. AND means both licenses apply. A scanner that reads OR as AND raises copyleft alerts for packages that carry no copyleft obligation. node-forge also shows a metadata problem: the [SPDX license list](https://spdx.org/licenses/) deprecated the bare GPL-2.0 identifier in license list version 3.0 because it does not say whether "or any later version" applies.

|  | Permissive (MIT, BSD, Apache-2.0) | Weak copyleft (MPL-2.0, LGPL) | Strong copyleft (GPL) | Network copyleft (AGPL) |
| --- | --- | --- | --- | --- |
| Owe source when you ship? | No | For the component only | For the whole program | For the whole program |
| Owe source when you only run it as a service? | No | No | No | Yes, if you modified it |
| Safe to link into a closed product you ship? | Yes | Yes, following the license's linking rules | No | No |
| Typical review cost | Attribution file | One-time review per component | Legal review per use | Legal review, often denied by policy |

Our verdict: as a consumer, treat permissive licenses as the default and weak copyleft as allowed after a one-time review of how each component is used. Treat strong and network copyleft as a decision about your product's distribution, not about the package. As an author, choose a weak copyleft license if you want improvements to your library returned without blocking commercial adopters. Choose the GPL or AGPL when keeping every derivative open matters more to you than adoption.

## How copyleft enters a dependency tree

A copyleft license usually enters a codebase as a [transitive dependency](https://socket.dev/glossary/transitive-dependency) that nobody chose. To measure this, we generated a fresh Next.js 16.4.3 app with create-next-app's default options, installed it with npm 12.2.1, and asked npm which installed packages declare a copyleft license:

```shell
$ npx create-next-app@latest demo --yes --skip-install --disable-git && cd demo && npm install
added 358 packages, and audited 359 packages in 38s

$ npm query ':is([license*=GPL],[license*=MPL],[license*=EPL],[license*=CDDL],[license*=EUPL])' \
    | jq -r '.[] | "\(.name)@\(.version)  \(.license)  dev=\(.dev)"'
@img/sharp-libvips-linux-x64@1.3.4  LGPL-3.0-or-later  dev=false
axe-core@4.14.0  MPL-2.0  dev=true
lightningcss@1.32.0  MPL-2.0  dev=true
lightningcss-linux-x64-gnu@1.32.0  MPL-2.0  dev=true
```

Three of the four come from developer tooling. axe-core, the accessibility engine, arrives through eslint-config-next and eslint-plugin-jsx-a11y. lightningcss, the CSS compiler, and its Linux binary arrive through Tailwind CSS 4.3.3. The fourth is in production: next declares sharp as an optional dependency, npm installs optional dependencies by default, and sharp pulls in a prebuilt libvips binary. The registry reported 76,118,281 downloads of sharp in the week of October 16 to 22, 2026 ([npm API](https://api.npmjs.org/downloads/point/last-week/sharp)). This is not an exotic path.

> None of the highlighted packages appear in the project's package.json. The registry metadata shows one license for the libvips package; its README lists nine copyleft components inside it.
>
> Dependency paths from a default create-next-app project to its four copyleft-licensed packages. Production path: next 16.4.3, MIT, to sharp 0.35.5, Apache-2.0, to the sharp-linux-x64 native addon, Apache-2.0, which dynamically links the sharp-libvips-linux-x64 1.3.4 binary. That binary declares LGPL-3.0-or-later and bundles 29 libraries, 8 under LGPLv3 and 1 under MPL-1.1. Development paths: eslint-config-next to eslint-plugin-jsx-a11y to axe-core 4.14.0, MPL-2.0; and @tailwindcss/turbopack to @tailwindcss/node to lightningcss 1.32.0 and its Linux binary, both MPL-2.0.

The tree above, as text. Production path: the project depends on next@16.4.3 (MIT), which optionally depends on sharp@0.35.5 (Apache-2.0), which depends on the native addon @img/sharp-linux-x64@0.35.5 (Apache-2.0, a 415 KB .node file). That addon dynamically links @img/sharp-libvips-linux-x64@1.3.4, an 18.7 MB shared library that declares LGPL-3.0-or-later and has 29 libraries compiled into it: eight under LGPLv3 (libvips, glib, pango, libheif, librsvg, libexif, fribidi, proxy-libintl), cairo under MPL-1.1, and 20 under permissive licenses. Development paths: eslint-config-next@16.4.3 depends on eslint-plugin-jsx-a11y@6.10.2, which depends on axe-core@4.14.0 (MPL-2.0); @tailwindcss/turbopack@4.3.3 depends on @tailwindcss/node@4.3.3, which depends on lightningcss@1.32.0 and lightningcss-linux-x64-gnu@1.32.0 (both MPL-2.0). None of the four copyleft packages appears in the project's package.json.

The libvips package is where metadata stops telling the truth. Its package.json has one license field. Its README, which a license-field check never reads, has a table of the 29 libraries inside the binary and the license each is used under. It also notes that the LGPLv3 libraries are used "via the 'any later version' clause of the LGPLv2 or LGPLv2.1," which is the "or later" mechanism doing real work: those libraries' authors released them under LGPLv2 or LGPLv2.1 "or any later version," and the packager chose version 3. Here is the binary layout, from readelf:

```shell
$ readelf -d node_modules/@img/sharp-linux-x64/lib/sharp-linux-x64-0.35.5.node | grep NEEDED
 0x0000000000000001 (NEEDED)  Shared library: [libvips-cpp.so.8.18.7]
 0x0000000000000001 (NEEDED)  Shared library: [libstdc++.so.6]
 ...
$ readelf -d node_modules/@img/sharp-libvips-linux-x64/lib/libvips-cpp.so.8.18.7 | grep NEEDED
 0x0000000000000001 (NEEDED)  Shared library: [libresolv.so.2]
 0x0000000000000001 (NEEDED)  Shared library: [libdl.so.2]
 0x0000000000000001 (NEEDED)  Shared library: [libstdc++.so.6]
 ...
$ nm -D --defined-only node_modules/@img/sharp-libvips-linux-x64/lib/libvips-cpp.so.8.18.7 | grep -c ' T g_'
1787
```

The Apache-2.0 addon loads libvips as a separate shared object at run time. This is the arrangement LGPLv3 Section 4(d)(1) describes, and it lets sharp stay Apache-licensed while depending on LGPL code. The libvips binary itself depends only on system C and C++ runtime libraries, and it exports 1,787 GLib functions: glib, pango, cairo, and the rest are compiled into it. A scanner that reads the license field sees LGPL-3.0-or-later. It does not see the MPL-1.1 cairo code inside the same file.

The gap is not specific to npm. In our [license analysis write-up](https://socket.dev/blog/socket-license-analysis), Django 5.1.1 contained seven distinct licenses across ten license files, including a copyleft license (CC-BY-SA-4.0) that PyPI's metadata did not show. That is why Socket's license analysis searches every file in a package for license and copyright data rather than trusting the manifest.

We think registries should fix this at the source. [PEP 770](https://peps.python.org/pep-0770/), accepted on April 11, 2025, reserves a .dist-info/sboms directory so a Python wheel can declare the native libraries bundled inside it, as our [coverage of PEP 770](https://socket.dev/blog/new-python-packaging-proposal-aims-to-solve-phantom-dependency-problem-with-sboms) describes. As of October 2026, npm's [package.json documentation](https://docs.npmjs.com/cli/v11/configuring-npm/package-json) defines a license field for the package's own license and nothing for the components a prebuilt binary contains. Until it does, the per-component license data in packages like this one lives in a Markdown table.

## When does a copyleft license require you to share source code?

A copyleft license requires you to share source code when you distribute the covered code, or for the AGPL, when you let users reach a modified version over a network. Whether you owe anything therefore depends less on which packages you installed than on how each one leaves your hands. The four copyleft packages in our Next.js project land in four different places:

| Package and license | How it is used | Distributed? | What you owe |
| --- | --- | --- | --- |
| lightningcss, MPL-2.0 | Compiles CSS at build time | No; you ship its output, not the tool | Nothing |
| axe-core, MPL-2.0 | Lint rules during development | No | Nothing, unless you bundle axe-core into a shipped app |
| sharp's libvips, LGPL-3.0-or-later | Image optimization on a server you operate | No | Nothing; running software is not conveying it |
| sharp's libvips, LGPL-3.0-or-later | Inside a container image, appliance, or desktop app you give to customers | Yes | LGPL text and notices, source for the bundled LGPL libraries, and no terms that block replacing them |

Build tools deserve the most precise reasoning. The legal question is whether the artifact you ship contains the tool's code. GPLv3 states the principle in its Section 2: "The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work." The stylesheet lightningcss emits is your CSS transformed, not a copy of lightningcss. Your obligations would start only if you redistributed lightningcss itself, and under MPL-2.0 they would cover only its files.

The server case is simpler than it looks. Distribution is a transfer of copies. A Next.js app running sharp on your own infrastructure transfers no copy of libvips to anyone, so the LGPL never activates. The same app shipped as a self-hosted product, an Electron app, or an on-premises appliance does transfer copies. That is when the obligations in the last row apply, and the separately linked shared library is what makes them cheap to meet. Only the AGPL changes the server case, through the Section 13 network clause described above.

Socket's license policy is built around the copyleft tiers described above. It groups copyleft into Weak, Strong, Network, and Maximal tiers, and lets a team Block, Warn, or Monitor each tier at the pull request that introduces a package ([docs](https://docs.socket.dev/docs/license-policy)). Socket evaluates SPDX expressions as expressions: if a dual-licensed package or dependency set can be taken under permissive terms only, Socket does not raise a Copyleft License alert ([details](https://socket.dev/blog/introducing-socket-license-detection)). A reasonable default for a company that ships a closed product: monitor weak copyleft, warn on strong copyleft so a person checks whether the code ships, and block network copyleft in libraries you import. A pure SaaS company can usually afford to relax the strong tier. That is a starting point for [license compliance](https://socket.dev/glossary/license-compliance), not legal advice. We are engineers, not your lawyers, and an actual combined-work question deserves an opinion on your specific architecture.

## Copyleft can appear or disappear in an upgrade

The license that binds you is the license of the exact version you resolved, so a copyleft license can enter or leave your tree on a routine upgrade. chardet, the Python character-encoding detector, shows both directions. Its per-version license metadata on [PyPI](https://pypi.org/project/chardet/#history):

| Version | Uploaded to PyPI | Declared license |
| --- | --- | --- |
| 6.0.0 | February 22, 2026 | LGPL-2.1-or-later |
| 7.0.0 | March 4, 2026 | MIT |
| 7.3.0 | March 24, 2026 | 0BSD |
| 7.7.0 | October 18, 2026 | 0BSD |

chardet was LGPL for two decades, and the license had already cost it adoption. When Requests 2.26.0 shipped on July 13, 2021, its [changelog](https://github.com/psf/requests/blob/main/HISTORY.md) explained the switch away from chardet: "use the MIT-licensed `charset_normalizer` for Python3 to remove license ambiguity for projects bundling requests." Until that release, every install of Requests pulled in chardet.

chardet 7.0.0 [described itself](https://github.com/chardet/chardet/releases/tag/7.0.0) as a "ground-up, MIT-licensed rewrite" with the same package name and public API, and its maintainer [used an AI coding agent](https://simonwillison.net/2026/mar/5/chardet) to write it. Mark Pilgrim, chardet's original author, objected in [issue #327](https://github.com/chardet/chardet/issues/327) and asked the maintainers to "revert the project to its original license." Richard Fontana, a co-author of GPLv3 and LGPLv3, [replied in issue #334](https://github.com/chardet/chardet/issues/334): "I don't currently see any basis for concluding that chardet 7.0.0 is required to be released under the LGPL." The maintainers closed and locked the original issue. The license then changed again, from MIT to 0BSD, in the minor release 7.3.0.

Two lessons follow for anyone running a license policy. First, a relicense does not reach backward. chardet 6.0.0 is LGPL permanently, and a lockfile pinned to it still carries LGPL terms after 7.x exists. Second, license changes do not respect [semantic versioning](https://socket.dev/glossary/semantic-versioning-semver). chardet's MIT-to-0BSD change shipped in a minor version. In the npm ecosystem, [ua-parser-js](https://socket.dev/blog/ua-parser-js-drops-mit-license) moved from MIT to AGPLv3 in its 2.0 release. Evaluate the license on every resolved version, at the pull request that changes it, not once per package name.

## How copyleft is enforced

Copyleft is enforced mostly by copyright holders, and the open question in the United States is whether ordinary users can enforce it too. In SFC v. Vizio, filed on October 19, 2021 in California Superior Court, the Software Freedom Conservancy argues that it can demand GPLv2 source code from Vizio as a purchaser of a Vizio TV, a third-party beneficiary of the license. On December 23, 2025, the court ruled that GPLv2 does not require Vizio to allow modified code to be reinstalled on its TVs. A [February 2026 order](https://www.bakerbotts.com/thought-leadership/publications/2026/may/when-consumers-enforce-open-source) sent the remaining questions toward trial. As of October 2026, the [SFC's case page](https://sfconservancy.org/copyleft-compliance/vizio.html) lists the case as ongoing, and we found no reported verdict.

The reinstallation ruling marks a real gap between license versions. GPLv3 and LGPLv3 added an explicit duty to provide "Installation Information" for consumer devices, after manufacturers shipped GPLv2 software in locked-down hardware. GPLv2 has no such clause. Which version a dependency uses is therefore not trivia: it changes what a device maker owes.

The harder open problem is the boundary itself. A copyleft license reaches exactly as far as copyright's idea of a derivative work, and two trends are straining that idea. Prebuilt binaries fuse dozens of libraries under one license string, so the boundary is invisible to anyone reading metadata. AI-assisted rewrites like chardet 7.0 claim to cross it with code that shares an API but, its maintainer argues, no expression. No court has tested either. Until one does, the only reliable inputs are the actual files in each package version and an honest account of where your software goes.
