Choosing an Open Source License for a Haskell Library
Open the license field of a hundred random packages on Hackage and you will see the same two answers again and again: BSD-3-Clause and MIT. Most authors did not pick them after reading anything.

Open the license field of a hundred random packages on Hackage and you will see the same two answers again and again: BSD-3-Clause and MIT. Most authors did not pick them after reading anything. They accepted whatever cabal init suggested, or copied the field from the last package they cloned, and moved on to the code.
That habit mostly works, but not always. Choosing an open source license for a Haskell library has a few quirks that do not apply in other ecosystems, mainly because GHC links Haskell code statically by default. This guide walks through the licenses you will actually meet, what each one means for the people who depend on you, and the mistakes I keep seeing in package reviews.
Why an Open Source License for a Haskell Library Matters
A license is the only document that tells a stranger what they are allowed to do with your code. Without one, the default under copyright law in most countries is that nobody may copy, modify or redistribute it, even if the repository is public. A package with an empty or "AllRightsReserved" license field is effectively unusable for any company with a legal review step.
The field also travels. Tools read it automatically, distributions such as Nixpkgs and Debian sort packages by it, and some employers block dependencies whose license is missing or unfamiliar. A two word decision ends up shaping who can adopt your library at all.
The Licenses You Will Actually Meet on Hackage
There are hundreds of approved licenses, but a Haskell author realistically chooses between five. Here is how they compare in practice.
| License | Type | What users must do | Typical fit |
|---|---|---|---|
| BSD-3-Clause | Permissive | Keep the copyright notice, do not use your name to endorse | General libraries, matches GHC and base |
| MIT | Permissive | Keep the copyright and license notice | Small utilities, quick adoption |
| Apache-2.0 | Permissive with patent grant | Keep notices, state significant changes | Libraries backed by a company |
| MPL-2.0 | File level copyleft | Share changes to your files only | Code you want improvements returned to |
| GPL-3.0 or LGPL | Strong or library copyleft | Release derived work under the same terms | Applications, rarely libraries |
BSD-3-Clause dominates for a simple reason: GHC, base and most of the core libraries use it. Matching them means a downstream user never has to think twice about mixing your package with the standard toolchain.
Static Linking Changes the Copyleft Math
This is the part that catches people coming from C or Python. In those worlds, the LGPL is attractive because a program can load an LGPL library dynamically and stay under its own license. The LGPL asks that end users be able to swap in a modified version of the library, which dynamic linking makes easy.
GHC does not work that way by default. A compiled Haskell executable contains every Haskell dependency baked in, and the code is heavily inlined across module boundaries. Relinking against a modified version of one library is not something a user can realistically do with a shipped binary. That means a plain LGPL Haskell library behaves much closer to the GPL than its author probably intended.
Some authors handle this with an LGPL plus a static linking exception, a short clause that explicitly allows static linking without triggering the relink requirement. If you want copyleft for the library itself but not for its users, that exception or the MPL-2.0 is a better fit than bare LGPL.
The Common Advice That Does Not Hold Up
You will often read that "MIT and BSD are basically the same, so pick either." For a single file utility, fine. For anything else, the differences are small but real.
- The endorsement clause. BSD-3-Clause forbids using your name to promote derived products. MIT says nothing about it. If your name or your company name carries weight, that clause has value.
- Patents. Neither MIT nor BSD-3-Clause includes an explicit patent grant. Apache-2.0 does, and it terminates the grant for anyone who sues over patents in the work. Larger companies sometimes prefer it for exactly this reason.
The other advice I push back on is "use GPL to stop companies from taking your work." In Haskell, companies mostly react by not using the library at all, writing a smaller internal version instead. If adoption matters to you, copyleft on a library is usually a cost, not a shield.
Writing the License Field Correctly
Since cabal-version 2.2, the license field accepts SPDX expressions. That means you write exact identifiers and you can combine them.
- Set cabal-version: 2.2 or higher at the top of the .cabal file.
- Write the identifier exactly, for example license: BSD-3-Clause rather than the old BSD3 spelling.
- For dual licensing, use an expression such as license: MIT OR Apache-2.0.
- Add license-file: LICENSE and make sure the file contains the full text with your name and the year.
- Run cabal check before uploading. It flags missing license files and unknown identifiers.
The most frequent error I see is a correct field with a LICENSE file still containing a template placeholder like "Author name here". Hackage accepts it, but the notice is legally weaker and looks careless to anyone reading the source tarball.
Checking Your Dependencies Before You Commit
Your license choice does not exist in isolation. If your library depends on a GPL package, anyone distributing a binary that uses your library is bound by the GPL anyway, whatever your own field says. Declaring MIT on top of a GPL dependency gives users a false sense of freedom.
The cabal-plan tool has a license-report command that walks the full build plan and lists every transitive dependency with its license. Run it once before your first release and again whenever you add a dependency. If you are still choosing which packages to build on, our overview of open source Haskell libraries in active use notes which ones are actively maintained.
Contributors, Relicensing and the Long Term
Every contributor who sends you a patch owns the copyright on their part unless they assign it. That matters the day you want to change licenses. Moving a project from GPL to BSD later requires permission from every contributor whose code remains, and on a project with forty contributors over eight years, some of them will be unreachable.
Two habits make this easier. First, decide the license before the first outside contribution, not after. Second, state in your CONTRIBUTING file that contributions are accepted under the project license, which is how most community packages handle it. You can read more about how maintainers organise this kind of shared work in how the Haskell community builds and maintains its packages.
Frequently Asked Questions
Can I change the license of my Haskell package after publishing it?
Yes, for future versions, as long as you hold the copyright on all the code or have permission from every contributor. Versions already on Hackage stay available under the license they were released with.
Does Hackage require a specific open source license?
No. Hackage accepts any valid license field, including proprietary ones, but packages without a recognised open source license are far less likely to be used or packaged by distributions.
Is dual licensing worth the extra complexity?
For most small libraries it is not. MIT OR Apache-2.0 makes sense if you expect corporate users who want a patent grant alongside users who prefer the shortest possible text.
A Practical Default
If you have no strong reason to do otherwise, use BSD-3-Clause, write it as an SPDX identifier, fill in the LICENSE file properly and run a dependency license report before each release. Pick copyleft only when you have a specific goal it serves, and if you do, prefer MPL-2.0 or LGPL with a static linking exception over plain LGPL. More guides in this area live under our open source section.
More in Open Source
Open Source
How Open Source Maintainers Decide What Features To Reject
Every popular open source project accumulates a long tail of feature requests that never get merged, and the people who...
Open Source
How the Haskell Community Builds and Maintains Its Packages
Open source package maintenance is unglamorous work. The developers who do it reliably and well enable everyone else in the...
Open Source
The Best Open Source Haskell Libraries in Active Use
The Haskell ecosystem has a reputation for being hard to navigate - lots of libraries, varying maintenance states, and...