# Apache License 2.0

> The Apache License 2.0 is a permissive open source license with an explicit patent grant; redistributors must keep its license text and NOTICE file.

Also known as: Apache 2.0, Apache-2.0, Apache License, Version 2.0, ALv2, ASL 2.0, Apache 2 license, Apache Software License

Source: https://socket.dev/glossary/apache-license-2-0

Last updated: 2026-10-25

The Apache License 2.0 (also written Apache 2.0, Apache-2.0, or ALv2) is a permissive open source license published by the Apache Software Foundation. It lets anyone use, modify, and sell the code, adds an explicit patent license that ends if you sue over the code, and requires redistributors to pass on the license text, change notices, and NOTICE files.

The patent grant is why companies choose the Apache License 2.0 over the [MIT License](https://socket.dev/glossary/mit-license). The notice rules are what they get wrong. In October 2026 we checked the 1,877 npm packages with at least a million weekly downloads that declare Apache-2.0. 208 ship a NOTICE file, and 300 more have one in their source repository that never reached the published tarball. When a package uses a `files` allowlist, npm and pnpm still pack its LICENSE file but silently drop its NOTICE file, and the default production builds of esbuild, webpack, and Vite contain neither the license text nor the NOTICE. Our position: the Apache License 2.0 is the right default for permissive code where patents matter, and its notice duty belongs in the build pipeline, where it is cheap to automate, not in a checklist someone forgets.

## What is the Apache License 2.0?

The Apache License 2.0 is a [permissive license](https://socket.dev/glossary/permissive-license): it grants broad rights and asks for attribution, not reciprocity. Start from the default. Copyright gives an author exclusive rights to copy, modify, and distribute code. Without a license, nobody else may do any of those things. A permissive license hands those rights to everyone, with conditions about notices rather than about source code.

The Apache Software Foundation (ASF) wrote version 2.0 to replace the BSD-style [Apache License 1.1](https://www.apache.org/licenses/), which the ASF approved in 2000. Version 2.0 is dated January 2004. Its SPDX identifier is `Apache-2.0`. Unlike version 1.1, its terms name no organization and apply to "the Work" by reference, so any project can adopt the text unmodified.

The license is nine numbered sections plus an appendix that shows how to apply it. Four of them carry almost all the weight:

| Section | What it does | What it means for you |
| --- | --- | --- |
| 2. Copyright license | Grants a "perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable" right to copy, modify, sublicense, and distribute | You may use the code commercially and keep your own code closed |
| 3. Patent license | Each contributor licenses the patent claims its contribution necessarily infringes, and the license ends if you sue claiming the Work infringes | You get patent protection that MIT and BSD never state |
| 4. Redistribution | Four conditions: give recipients the license, mark changed files, keep existing notices, carry the NOTICE file | This is the entire compliance burden |
| 6. Trademarks | Grants no right to use the licensor's names or marks | A fork must not ship under the original name |

The definitions in Section 1 settle the question developers ask most. "Derivative Works" excludes works that "remain separable from, or merely link (or bind by name) to the interfaces of, the Work." Importing an Apache-licensed library does not turn your application into a derivative work of it. Even if it did, nothing in the license would require you to publish your source. That is the core difference from a [copyleft license](https://socket.dev/glossary/copyleft-license).

## How does the Apache License 2.0 patent grant work?

The Apache License 2.0 patent grant gives every user a license to each contributor's patents that the contributed code necessarily infringes. It covers the contribution alone and its combination with the Work it was submitted to. It does not cover your later modifications or unrelated products. Section 3 then attaches a defensive termination clause:

```text
If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
```

Three details in that sentence decide how much it costs you. The trigger is a suit claiming the Work infringes, filed against "any entity," so suing another user counts, not just suing the author. Only the patent licenses terminate, so your copyright license under Section 2 survives. And termination applies only "for that Work," so a patent fight over one Apache project leaves your licenses to every other Apache project intact.

The narrowness is the point, and React shows what the alternative looked like. Until September 2017, React shipped under BSD-3-Clause plus a separate PATENTS file. We pulled that file from the react@15.6.1 tarball on npm. Its grant terminated if you brought a patent assertion "against Facebook or any of its subsidiaries or corporate affiliates," for any patent and any product, not just React. The two clauses compared on the same scenarios:

| Scenario | Apache License 2.0, Section 3 | React 15.6.1 PATENTS grant |
| --- | --- | --- |
| You sue anyone claiming the licensed project infringes your patent | Patent license for that project ends | Patent grant ends |
| You sue the licensor over an unrelated patent and product | Nothing ends | Patent grant ends |
| The licensor sues you first and you counterclaim over unrelated patents | Nothing ends | Grant survives, by an explicit carve-out |
| Your copyright license after termination | Survives | Survives, because BSD-3-Clause has no termination |

The ASF lists Facebook's BSD+Patents license in [Category X](https://www.apache.org/legal/resolved.html), the set its projects may not ship, because it "passes along risk to downstream consumers of our software imbalanced in favor of the licensor, not the licensee." Facebook [announced on September 22, 2017](https://engineering.fb.com/2017/09/22/web/relicensing-react-jest-flow-and-immutable-js/) that React, Jest, Flow, and Immutable.js would move to MIT. npm records react@15.6.2 and react@16.0.0, both published September 26, 2017, as MIT.

We think Section 3 is the best patent clause in common use for permissive code. It is symmetric, scoped to the project, and costs nothing unless you sue over the project itself. MIT and BSD say nothing about patents, so any patent permission under them has to be implied. Nobody has to argue about an express grant.

## Is Apache License 2.0 free for commercial use?

The Apache License 2.0 is free for commercial use. Section 2 grants its rights at no charge and royalty-free, and the grant includes the right to sublicense. You may sell software that contains Apache-licensed code, ship it in a closed-source product, and charge for support or warranties, which Section 9 explicitly allows. You owe no royalties and no source code.

What you may not do is drop the conditions. The last sentence of Section 4 lets you license "Your modifications" or a "Derivative Works as a whole" under different terms, "provided Your use, reproduction, and distribution of the Work otherwise complies" with the license. The Apache-licensed parts keep their notices inside your commercial product. Section 6 adds that you get no trademark rights, so a fork needs its own name.

The same freedom works against users when a project's owner closes future versions. In the [Elasticsearch license change](https://socket.dev/blog/developers-burned-by-elasticsearch-license-change-arent-going-back) of 2021, Elastic moved Elasticsearch from the Apache License 2.0 to SSPL and the Elastic License. Because every earlier version stayed Apache-licensed, AWS forked that code as OpenSearch. [The Fluent Assertions relicense](https://socket.dev/blog/fluent-assertions-faces-backlash-after-abandoning-open-source-licensing), which we covered in January 2025, went further. Version 8 of the .NET library moved from the Apache License 2.0 to a commercial license priced at $129.95 per person per year, and critics argued that community contributions made under the Apache License 2.0 could not be relicensed.

The license text is less protective than those critics hoped. Section 5 makes every contribution Apache-licensed by default, and an Apache license permits exactly what Section 4 describes: shipping the code inside a differently licensed derivative, with the notices intact. What no one can do is revoke the Apache License 2.0 on code already released, since Section 2 calls the grant "irrevocable." The ethical objection is fair. The practical lesson is the one from every permissive relicense: the old versions are yours forever, and the next major version may not be. We are engineers, not your lawyers, and a real relicensing dispute deserves a legal opinion.

## What does the Apache License 2.0 require when you redistribute?

The Apache License 2.0 requires four things whenever you redistribute the code, modified or not, in source or compiled form. Section 4 states them as conditions on the permission to redistribute:

- **4(a)** Give every recipient a copy of the license.
- **4(b)** Mark any file you modified with a prominent notice that you changed it.
- **4(c)** Keep the copyright, patent, trademark, and attribution notices already in the source.
- **4(d)** If the Work includes a NOTICE file, include a readable copy of its attribution notices in your distribution. That copy can live in your own NOTICE file, in your source or documentation, or in a display your software shows "if and wherever such third-party notices normally appear."

The NOTICE file is the Apache License 2.0's distinctive mechanism. It is a plain text file at the root of a project that holds attributions that must travel with the code. It descends from clause 3 of [Apache License 1.1](https://spdx.org/licenses/Apache-1.1.html), which required redistributors' documentation to say "This product includes software developed by the Apache Software Foundation." Version 2.0 generalizes that clause: each project writes its own required acknowledgments into NOTICE, and the license obliges everyone downstream to carry them. The license says its contents "are for informational purposes only and do not modify the License," so a NOTICE file can add attribution but cannot add restrictions. The ASF's [licensing guide](https://infra.apache.org/licensing-howto.html) tells its own projects to put nothing in NOTICE that is not legally required: "It is important to keep NOTICE as brief and simple as possible, as each addition places a burden on downstream consumers."

That burden is why the [Blue Oak Council](https://blueoakcouncil.org/list), which rates permissive licenses, puts the Apache License 2.0 in its Silver tier rather than Gold. Its Silver tier covers licenses that "fail to address patents explicitly or require more than simple notice." MIT is Silver for the first reason. The Apache License 2.0 is Silver for the second.

## Where the NOTICE file gets lost

A NOTICE file only works if it travels with the code, and modern packaging tools were built around LICENSE files, not NOTICE files. npm's [package.json documentation](https://docs.npmjs.com/cli/v12/configuring-npm/package-json#files) lists what npm always packs regardless of the `files` field: `package.json`, `README`, `LICENSE` or `LICENCE`, and the files named in `main` and `bin`. NOTICE is not on the list. Any package with a `files` allowlist drops its NOTICE file unless a maintainer remembers to add it. We reproduced this with npm 12.2.1 on a package that has LICENSE, NOTICE, and `"files": ["dist"]`:

```bash
$ ls
LICENSE  NOTICE  README.md  dist  package.json
$ npm pack --dry-run
npm notice Tarball Contents
npm notice 20B LICENSE
npm notice 7B README.md
npm notice 19B dist/index.js
npm notice 132B package.json
npm notice total files: 4
```

pnpm 12.15.0 produced the same four files. The other major registries handle this better:

| Packaging tool (October 2026) | NOTICE packed by default? | LICENSE packed by default? |
| --- | --- | --- |
| npm 12.2.1, with a files allowlist | No | Yes, always |
| pnpm 12.15.0, with a files allowlist | No | Yes, always |
| setuptools 84.2.1 wheel | Yes, recorded as License-File: NOTICE | Yes |
| hatchling 1.32.4 wheel | Yes, recorded as License-File: NOTICE | Yes |
| Cargo 1.97.0, default | Yes, the whole package directory ships | Yes |
| Cargo 1.97.0, with an include list | No | No, unless listed or set as license-file |

The npm gap shows up in real packages. [@opentelemetry/instrumentation-kafkajs](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/instrumentation-kafkajs) 0.33.0, published October 20, 2026, keeps a NOTICE file in its own package directory at the release tag. The file credits the original instrumentation written by Aspecto and lists the changes OpenTelemetry made, which is exactly the attribution and change notice Sections 4(b) and 4(d) exist to carry. Its `files` field is `["README.md", "LICENSE", "dist"]`, and the tarball on npm has no NOTICE.

The pattern holds across the registry. We took the 15,916 packages on the [npm-high-impact](https://www.npmjs.com/package/npm-high-impact) 1.13.0 list, each downloaded at least 1,000,000 times a week when the list was compiled, and fetched the latest manifest for 15,910 of them on October 25, 2026. Then we listed the tarball of every package whose license field includes Apache-2.0:

| Measurement | Count |
| --- | --- |
| Packages declaring a license that includes Apache-2.0 | 1,877 of 15,910 (11.8%) |
| Of those, tarballs with a NOTICE file at the package root | 208 |
| Tarballs declaring exactly Apache-2.0 with no NOTICE whose GitHub repository has one, at the root or in the package directory | 300 of 1,590 |
| Tarballs with no LICENSE, LICENCE, or COPYING file at the package root | 273 |

The 300 cluster in large monorepos, including 115 packages from Adobe's React Spectrum and 52 from the Smithy TypeScript packages that underpin the AWS SDK. Not every root NOTICE in a monorepo pertains to every package, so the count overstates the true losses somewhat. The 273 packages with no license file at all are the other failure. firebase 13.1.0 ships 2,974 files, and none of them is a license file. The per-file headers point to a URL instead, and the repository's root [LICENSE](https://github.com/firebase/firebase-js-sdk/blob/main/LICENSE) never reaches the package directory npm publishes. Section 4(a) asks whoever redistributes firebase to hand over a copy of the license, and the package does not hand one to them.

Python shows the difference tooling makes. Among the 500 most downloaded projects on PyPI (October 1, 2026 snapshot), 138 declare the Apache License 2.0 by expression, classifier, or license field. 16 of their 137 wheels carry a NOTICE file in `.dist-info`, among them requests, boto3, and pyarrow. That is roughly the same share as npm. The difference is that a Python maintainer gets NOTICE shipped without doing anything, and an npm maintainer who uses a `files` allowlist has to remember.

Registry metadata cannot tell you any of this, because the license field says Apache-2.0 either way. Analyze what is actually in the package, not what its metadata claims. Socket's [license analysis](https://socket.dev/blog/socket-license-analysis) reads license, copyright, and attribution data from every file in a package rather than the manifest alone, and can generate attribution data for a whole dependency set through the package License panel or the API.

## Bundlers strip Apache notices from production builds

A JavaScript bundle is the Work in "Object" form, which the license defines as anything produced by "mechanical transformation or translation of a Source form," including compiled code. Shipping a bundle to browsers is redistribution, so Section 4 applies. The tools that build bundles keep only comments marked as legal. esbuild [defines a legal comment](https://esbuild.github.io/api/#legal-comments) as one that "contains `@license` or `@preserve` or that starts with `//!` or `/*!`." The Apache License 2.0's standard source header is a plain `/*` comment, so minifiers treat it like any other comment and delete it.

We tested this with Apache ECharts 6.1.0, an ASF project that does everything right. Its npm tarball ships LICENSE and NOTICE, and all 591 JavaScript files in `lib/` carry the ASF license header. We bundled a three-line bar chart with each tool's default production settings and searched the output:

```bash
$ npx esbuild src/main.js --bundle --minify --outfile=out/esbuild.js
$ grep -c "Apache Software Foundation" out/esbuild.js
0
$ grep -o "Bundled license information:" out/esbuild.js
Bundled license information:
```

| Bundler (default production build) | Output size | Apache license text or ASF notice kept | Legal comments kept from other packages |
| --- | --- | --- | --- |
| esbuild 0.28.2 | 1,133,878 bytes | None | tslib (0BSD) and zrender (BSD-3-Clause), at end of file |
| webpack 5.112.2 | 1,113,789 bytes | None | tslib and zrender, extracted to main.js.LICENSE.txt |
| Vite 8.3.5 | 1,117,411 bytes | None | None |

The result is backwards. esbuild and webpack preserve the notice for tslib, whose 0BSD license requires no notice at all, because tslib marks its header `/*!`. They delete every trace of ECharts' Apache License 2.0, the license in the bundle with the heaviest notice duty. A browser that loads the bundle receives ECharts' code, no copy of the Apache License 2.0, and no NOTICE. A plugin can fix it, but only if someone installs it. In our tests, rollup-plugin-license 3.7.1 under Vite copied ECharts' NOTICE into its third-party output. license-webpack-plugin 4.0.2 reads LICENSE files but not NOTICE files, and with webpack's default module concatenation it listed only tslib and missed both ECharts and zrender.

The figure traces the three kinds of notice through each stage, from source repository to browser.

> Which Apache License 2.0 notices survive each stage from source repository to browser bundle

The figure as text. At the source repository stage, all three notices exist: the LICENSE file, the NOTICE file, and the license header at the top of each source file. Publishing to npm keeps LICENSE, because npm always packs it, and keeps the headers inside files, but keeps NOTICE only if it is listed when the package uses a `files` allowlist. Among Apache-licensed npm packages with at least 1,000,000 weekly downloads, 300 have a NOTICE in their repository that their tarball lacks. Installing into node\_modules changes nothing: whatever the tarball held is there. Minified bundling with esbuild 0.28.2, webpack 5.112.2, or Vite 8.3.5 removes all three, because none of them is a file the bundler copies and the headers are not marked as legal comments. In the ECharts test, 0 of 591 headers survived. The only way the notices reach the browser is a third-party notices file or page that a build step generates on purpose.

The LLVM project hit this problem in compilers and wrote the fix into its license. LLVM ships under the Apache License 2.0 with the LLVM Exception, SPDX identifier `Apache-2.0 WITH LLVM-exception`, whose first paragraph waives the notice conditions for code a compiler embeds in your binary:

```text
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into an Object form of such source code, you
may redistribute such embedded portions in such Object form without complying
with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
```

For a plain Apache-2.0 dependency there is no such waiver. The cheapest compliant setup is a build step that writes a third-party notices file containing every bundled package's LICENSE and NOTICE text, served at a stable URL or linked from your app's about screen. Section 4(d) explicitly accepts a display "wherever such third-party notices normally appear." Before that, the [license compliance](https://socket.dev/glossary/license-compliance) question is which packages are in the bundle at all. A [software bill of materials](https://socket.dev/glossary/software-bill-of-materials) answers that, though an SBOM records a license identifier, not the NOTICE text you owe.

## Is the Apache License 2.0 compatible with the GPL?

The Apache License 2.0 is compatible with GPLv3 in one direction and incompatible with GPLv2. The ASF's [compatibility page](https://www.apache.org/licenses/GPL-compatibility.html) states that Apache License 2.0 software "can therefore be included in GPLv3 projects," and that GPLv3 code cannot be included in Apache projects. The combined work ships under GPLv3. GPLv2 is different: "the FSF has never considered the Apache License to be compatible with GPL version 2," citing the patent termination and indemnification provisions as restrictions not present in GPLv2.

That incompatibility is why Rust, and much of its ecosystem, uses two licenses. The [Rust API guidelines](https://rust-lang.github.io/api-guidelines/necessities.html) recommend `license = "MIT OR Apache-2.0"` in Cargo.toml for "maximum compatibility with the Rust ecosystem." Graydon Hoare, who started Rust, explained the second license in [a December 2018 Rust internals thread](https://internals.rust-lang.org/t/rationale-of-apache-dual-licensing/8952): "GPLv2 compatibility is the one weird case that we needed to retain the nearly-redundant MIT for." Contributors grant the Apache patent license, and recipients can choose MIT when they need to combine with GPLv2 code. The [SPDX](https://socket.dev/glossary/spdx) operator `OR` means the recipient picks one.

The convention dominates the most downloaded crates. On October 25, 2026 we read the license of the default version of the 500 most downloaded crates on [crates.io](https://socket.dev/glossary/crates-io):

| License expression | Crates |
| --- | --- |
| MIT OR Apache-2.0, in either order or the older MIT/Apache-2.0 form | 310 |
| Apache-2.0 alone | 12 |
| Any other expression that includes Apache-2.0 | 33 |
| MIT alone | 97 |
| Everything else | 48 |

355 of the 500, or 71%, offer the Apache License 2.0. Only 12 offer nothing else. Five crates use a three-way choice that adds `Apache-2.0 WITH LLVM-exception`, whose second paragraph lets you drop the conflicting sections when you link with GPLv2 code. That exception solves the same problem Rust's dual license solves, with one license instead of two.

## Apache License 2.0 vs MIT vs BSD

The Apache License 2.0 is the permissive license with an express patent grant. MIT and BSD-3-Clause are shorter and lighter on notices. How each common choice compares:

|  | MIT | BSD-3-Clause | Apache-2.0 | MIT OR Apache-2.0 | Apache-2.0 WITH LLVM-exception |
| --- | --- | --- | --- | --- | --- |
| Express patent grant | No | No | Yes | Yes, if the recipient takes Apache | Yes |
| Defensive patent termination | No | No | Yes, scoped to the Work | Only under the Apache option | Yes |
| What redistributors must carry | Copyright and permission notice | Copyright notice, conditions, disclaimer | License copy, change notices, existing notices, NOTICE contents | Either set, at the recipient's choice | Same as Apache, waived for compiled-in portions |
| No-endorsement or trademark clause | No | Yes | Yes, Section 6 | Under the Apache option | Yes |
| GPLv2-compatible | Yes | Yes | No | Yes, via MIT | Yes, by the exception |
| GPLv3-compatible | Yes | Yes | Yes | Yes | Yes |
| Blue Oak tier | Silver | Bronze | Silver | Silver for each option | Not listed |

Our verdict. For a new library where patents could matter, such as compression, codecs, cryptography, or anything from a company with a patent portfolio, choose the Apache License 2.0. If your code may need to be combined with GPLv2 code, choose `MIT OR Apache-2.0` and keep both license files. For code that compiles into other people's binaries, `Apache-2.0 WITH LLVM-exception` is the most complete answer on paper, but it is rare outside compiler toolchains, so expect to explain it to reviewers. Choose plain MIT for small utilities, where the Apache notice machinery costs more than the patent grant is worth.

As a consumer, the risk is not in the license but in your build. A policy that allows Apache-2.0 still has to deliver the NOTICE files the license requires. A tool that lists Apache-2.0 as approved, without collecting those NOTICE files, approves code you are not shipping in compliance.

## The NOTICE model was built for release tarballs

The NOTICE mechanism made sense for how the ASF distributed software in 2004: a project published one source release, a few binaries, and a NOTICE file next to each. A modern web app inverts every part of that. It pulls hundreds of packages, each published separately by a different maintainer, through a packager that drops NOTICE files from allowlisted packages and a bundler that deletes license comments. It then ships a single minified file to every visitor.

The fixes are small and belong upstream. npm and pnpm should add NOTICE to the files they always pack, as Python's build backends already do. Bundlers should treat a dependency's LICENSE and NOTICE files as build outputs, the way esbuild already treats `/*!` comments. Until they do, every application that bundles Apache-licensed code needs one build step its toolchain will not run by default, and the Apache License 2.0's attribution condition will keep failing silently in production.
