Most projects get a license by copying whatever the last project used. This post explains what the main licenses actually ask of people who use your code, how to choose one with three questions, and what the licenses of your dependencies ask of you.
This is a developer's overview, not legal advice. For anything with money, a company or a contract behind it, ask a lawyer who knows software licensing in your country.
A license is permission given in advance
Code you write is protected by copyright from the moment you write it. Copyright is the default, and it is restrictive: nobody may copy, change or share your work without your permission.
So a license is not a restriction you add. A license is permission you give in advance, to people you will never meet, in writing, so that nobody has to ask you. Everything else — the differences between MIT, Apache and the GNU licenses — is about what you ask for in return.
This also explains the most common mistake. A public repository with no license file is not free to use. Without a license, the default applies: exclusive copyright[1]. Publishing on GitHub adds only what GitHub's terms give: other people may view your repository and fork it there, which is not permission to use the code in their own project[1]. A project with no license is, legally, a project nobody is allowed to use.
Three questions decide which license you want
You don't need to read license texts to choose one. Three questions separate the main options.
- Must people keep your name on it? Almost every open-source license says yes: whoever ships your code must include your copyright line and the license text. Only the public-domain-style licenses drop this.
- Must people who change your code publish their changed version? This is the "copyleft" idea: the license travels with the code, so improvements come back to everyone. Permissive licenses say no; the GNU licenses say yes.
- Does running your code as a web service count as giving it to someone? Under most licenses it does not: a company can run a changed version of your program on its servers and never publish anything. One license closes that gap.
Your answers lead to one of four groups:
The rest of this post explains what each group asks for, so you can be sure of your answers.
What each family asks for
The names first, because they are all shortened: MIT is named after the Massachusetts Institute of Technology, BSD after the Berkeley Software Distribution, GPL is the GNU General Public License, AGPL the GNU Affero General Public License, LGPL the GNU Lesser General Public License, and MPL the Mozilla Public License.
The families sit on a line, from "do anything" to "everyone downstream must share":
MIT and BSD-3-Clause are the short permissive ones. Anyone may use, change and sell your code, including inside closed-source products. The only condition is that they keep your copyright line and the license text, and you give no warranty[2]. MIT is about fifteen lines long, which is a real advantage: people read it and understand it.
Apache-2.0 is the permissive one with legal machinery. It has the same freedoms, plus three things MIT lacks[2][3]:
- A patent grant. Every contributor gives users a patent license for their contribution. If a user sues someone over a patent covering the work, their own patent license ends. This protects users of your project from the people who wrote it.
- "State changes". Anyone shipping a modified file must mark it as changed.
- The NOTICE file. If your project ships a
NOTICEfile with attribution text, anyone redistributing it must pass that text on.
MPL-2.0 is copyleft at the file level. If someone changes one of your files and ships the result, they must publish that file's source under MPL-2.0. The rest of their program, including closed-source parts that use your code, stays theirs[2]. This is the usual choice when you want changes to come back but don't want to stop companies from building products on top.
GPL-3.0 is copyleft for the whole program. Whoever distributes software built from your code must publish the complete source of that software, under the GPL, with any changes marked[2]. "Distributes" is the key word: a company may change GPL code and use it internally forever without publishing anything, as long as it doesn't give the program to anyone.
AGPL-3.0 closes the web-service gap. Its section 13 says that if users interact with your program over a network, the operator must "prominently offer" those users a way to download the source of the version they are using, free of charge[4]. This is why many companies do not allow AGPL code in their products at all — which may be exactly what you want, if your plan is to sell those companies a different license.
The Unlicense and CC0 give the code away with no conditions, not even attribution[2]. They are fine for examples and small snippets. For anything bigger, prefer MIT: it costs the user nothing more than a copied notice, and it keeps the warranty disclaimer, which the public-domain-style texts handle less clearly in some countries.
Side by side:
| License | Keep your notice | Publish changed source | Patent grant | Typical use |
|---|---|---|---|---|
| Unlicense / CC0 | Snippets, examples | |||
| MIT · BSD-3-Clause | Libraries you want widely used | |||
| Apache-2.0 | Libraries from or for companies | |||
| MPL-2.0 | Components you want improved | |||
| GPL-3.0 | Applications, tools | |||
| AGPL-3.0 | Server software, dual licensing |
The ten minutes: choosing and applying one
For a normal project — a library, a tool, a side project you might show an employer — the honest default is MIT, or Apache-2.0 if you or your users care about patents. Both are simple to apply correctly, and applying one takes four steps.
-
Add a
LICENSEfile at the root of the repository. Copy the full text from choosealicense.com and fill in the year and your name. The file name matters: GitHub, npm and license-scanning tools look forLICENSEorLICENSE.mdand show the license on the repository page. -
Write the identifier in your package metadata. Every ecosystem has a field for it. Use the standard short name from the SPDX License List (Software Package Data Exchange), the list that gives every license a fixed identifier such as
MIT,Apache-2.0orAGPL-3.0-only[5]. In a Node.js package:{"name": "my-package","version": "1.0.0","license": "MIT"}For a private package that nobody may use, npm (the Node.js package manager) has a special value,
"license": "UNLICENSED"[6]. Note the trap:UNLICENSEDmeans "no permission given", while the Unlicense is a license that gives everything away. One letter, opposite meanings. -
Say it once in the README. One line at the bottom — "MIT © Your Name" — with a link to the file. Don't let the README be the only place: a line in a README is a claim, and the
LICENSEfile is the thing people and tools read. -
If you chose Apache-2.0, add the header and the
NOTICEfile. The license text comes with a short header block to put at the top of source files, and theNOTICEfile holds the attribution text that redistributors must pass on[3].
Two decisions belong to this moment, because they are painful later:
- Every contributor's code is theirs. They license it to the project under the project's license. If you later want to change the license, you need the agreement of everyone whose code is still in the repository. Big projects avoid this by asking contributors to sign an agreement up front. Small projects mostly avoid it by choosing once and not changing.
- You can always give someone different terms. As the copyright holder, you can license the same code to a company under a private contract while the public copy stays AGPL. That is dual licensing, and it only works if you hold the rights to all the code — which brings you back to the first point.
What other people's licenses ask of you
The same rules run in the other direction. Every dependency you install comes with a license, and that license is a contract you accepted by shipping the code. Four obligations cover almost all of it:
- Pass on the notices. The most common obligation, and the most commonly forgotten. If you ship a product that includes MIT or Apache code — including a JavaScript bundle sent to a browser, or a mobile app — the copyright lines and license texts must travel with it. This is why applications have a "Third-party licenses" screen. Bundlers can produce that file for you; for example a plugin that collects the license text of every dependency into one file you ship next to the bundle.
- Mark your changes. Apache-2.0 asks you to note which files you changed[3]. This matters when you copy a file into your project and edit it, which is the usual way people break this rule without noticing.
- Publish your source, if a copyleft license reaches your code. With GPL-3.0 this happens when you distribute a program built from it; with AGPL-3.0 it also happens when you only run it as a service[4]. With MPL-2.0 it covers the files you changed, and nothing else[2].
- Don't use the project's name to sell yours. Apache-2.0 and MPL-2.0 say this explicitly: the license gives you the code, not the trademark[2].
A practical habit: check the licenses of your dependencies before the project grows, not after. Most ecosystems have a command that prints the license of every installed package, and printing a summary is enough to catch the one AGPL package that arrived as a dependency of a dependency.
Mixing licenses has one direction rule worth remembering. Permissive code can go into a copyleft project, but not the other way around. The Apache Software Foundation states both halves plainly: "Apache 2 software can therefore be included in GPLv3 projects", while "GPLv3 software cannot be included in Apache projects"[7]. The same asymmetry is why one GPL dependency can decide the license of everything you ship with it.
| You want to ship | With an MIT/Apache dependency | With a GPL-3.0 dependency |
|---|---|---|
| A closed-source product | ||
| An MIT-licensed library | ||
| A GPL-3.0 application | ||
| A web service you never distribute |
Five mistakes that cost real time
- No license file. The project looks open and is not. People who care about licensing — the ones at companies, who might have adopted your library — quietly skip it.
- The license only in the README, or only in
package.json. Tools and lawyers look for the file. Keep all three, saying the same thing. - A modified license. "MIT, but not for commercial use" is not MIT, and it is not open source. If you add conditions, the license is now custom and every company's legal review will stop on it. Use a source-available license that already exists, or write the terms with a lawyer.
- Copied code with its notice removed. A file taken from another project keeps its license, whether or not you keep its header. This applies to code a coding assistant suggested from a well-known source as well; when a snippet looks like it came from somewhere, find out where.
- Changing the license after other people contributed. Without their agreement, you cannot. Decide early.
The short version
- No license means nobody may use it. Add a file on day one.
- MIT if you want your code used everywhere with the least friction. Apache-2.0 if patents matter to you or to the companies you hope will adopt it.
- GPL-3.0 if changed versions must stay open, and AGPL-3.0 if that must include companies who only run it as a service. MPL-2.0 when you want the middle: your files stay open, their product stays theirs.
- Write the SPDX identifier in your package metadata, keep the
LICENSEfile at the root, and add theNOTICEfile if you chose Apache-2.0. - In the other direction, ship the notices of every dependency, and check your dependency licenses before, not after, you build a product on them.
Ten minutes, once, at the start of the project. The cost of choosing a license is a few minutes; the cost of not choosing one is that your project is unusable to exactly the people you wanted to reach.
References
- No License — choosealicense.com (GitHub)
- Licenses — choosealicense.com (GitHub)
- Apache License, Version 2.0 — The Apache Software Foundation
- GNU Affero General Public License v3.0, section 13 — Open Source Initiative
- SPDX License List — The Linux Foundation
- package.json — license — npm documentation
- GPL Compatibility — The Apache Software Foundation
